Регистрация  |  Вход

Unit тесты в salesforce.

Доброго времени суток сеньоры. Столкнулся с стеной непонимания в области покрытия тестами кода... есть вот такие вот методы

public void Sort(){
System.debug('OrderField = ' + OrderField );
OrderByValue = ' ORDER BY ' + OrderField;
if (OrderType == ' ASC ')
{
OrderType = ' DESC ';
queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
OrderByValue + OrderType + 'LIMIT:LimitSize OFFSET:count';
}
else
{
OrderType = ' ASC ';
queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
OrderByValue + OrderType + 'LIMIT:LimitSize OFFSET:count';
}
ContactList = DataBase.query(queryString);
}

написал метод для тестирования (как я думал)

@isTest static void Sort(){
string OrderByValue;
string OrderField;
string searchString = '';
integer count= 0;
integer LimitSize= 10;

string OrderTypeValue = (' ASC ');

List<String> OrderFieldValue = new List<String>();
OrderFieldValue.add('Name');
OrderFieldValue.add('Email');
OrderFieldValue.add('Contact_Level__c');
OrderFieldValue.add('AccountId');
OrderFieldValue.add('OwnerId');
OrderFieldValue.add('CreatedById');
OrderFieldValue.add('Created_Date__c');

string queryString ='SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\' LIMIT:LimitSize OFFSET:count';
List<Contact> ContactList = DataBase.query(queryString);

for (Integer i=0; i<(OrderFieldValue.size()-1); i++){
OrderByValue = ' ORDER BY ' + OrderFieldValue[i];
if (OrderTypeValue == ' ASC ')
{
OrderTypeValue = ' DESC ';
queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
OrderByValue + OrderTypeValue + 'LIMIT:LimitSize OFFSET:count';
}
else
{
OrderTypeValue = ' ASC ';
queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
OrderByValue + OrderTypeValue + 'LIMIT:LimitSize OFFSET:count';
}
ContactList = DataBase.query(queryString);
}

}


Тесты проходят, но не метод контроллера не считается покрытым. Попробовал другой метод
public PageReference NewContact(){
PageReference page = new PageReference('/apex/CreateNewContactView');
return page;

@isTest static PageReference NewContact(){
PageReference page = new PageReference('/apex/CreateNewContactView');
return page;

В последнем если честно вообще не понимаю как иначе можно протестировать... А ещё есть кучка методов пагинации

public PageReference Firstbtn() {
count=0;
getContacts();
return null;
}
public PageReference prvbtn() {
count=count-limitsize;
getContacts();
return null;
}
public PageReference Nxtbtn() {
count=count+limitsize;
getContacts();
return null;
}
public PageReference lstbtn() {
count = totalrecs - math.mod(totalRecs,LimitSize);
getContacts();
return null;
}
public Boolean getNxt() {
if((count + LimitSize) > totalRecs)
return true;
else
return false;
}
public Boolean getPrv() {
if(count== 0)
return true;
else
return false;
}

Подскажите пожалуйста как вообще подобные вещи тестируются в Salesforce.

 Доброго времени суток сеньоры. Столкнулся с стеной непонимания в области покрытия тестами кода... есть вот такие вот методы
[code]
    public void Sort(){
        System.debug('OrderField = ' + OrderField );
        OrderByValue = ' ORDER BY ' + OrderField;
        if (OrderType == ' ASC ')
        {
            OrderType = ' DESC ';
            queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
                OrderByValue + OrderType + 'LIMIT:LimitSize OFFSET:count';
        }
        else
        {
            OrderType = ' ASC ';
            queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
                OrderByValue + OrderType + 'LIMIT:LimitSize OFFSET:count';
        }
        ContactList = DataBase.query(queryString);
    }[/code]

написал метод для тестирования (как я думал)

[code]
    @isTest static void Sort(){
        string OrderByValue;
        string OrderField;
        string searchString = '';
        integer count= 0;
        integer LimitSize= 10;
        
        string OrderTypeValue = (' ASC ');
        
        List<String> OrderFieldValue = new List<String>();
        OrderFieldValue.add('Name');
        OrderFieldValue.add('Email');
        OrderFieldValue.add('Contact_Level__c');
        OrderFieldValue.add('AccountId');
        OrderFieldValue.add('OwnerId');
        OrderFieldValue.add('CreatedById');
        OrderFieldValue.add('Created_Date__c');
        
        string queryString ='SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\' LIMIT:LimitSize OFFSET:count';
        List<Contact> ContactList = DataBase.query(queryString);
        
            for (Integer i=0; i<(OrderFieldValue.size()-1); i++){
                OrderByValue = ' ORDER BY ' + OrderFieldValue[i];
                if (OrderTypeValue == ' ASC ')
                {
                    OrderTypeValue = ' DESC ';
                    queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
                        OrderByValue + OrderTypeValue + 'LIMIT:LimitSize OFFSET:count';
                }
                else
                {
                    OrderTypeValue = ' ASC ';
                    queryString = 'SELECT Name, Email, OwnerId, Contact_Level__c, Created_Date__c, AccountId, CreatedById FROM Contact WHERE Name LIKE \'%'+searchString+'%\''+
                        OrderByValue + OrderTypeValue + 'LIMIT:LimitSize OFFSET:count';
                }
                ContactList = DataBase.query(queryString);
            }

    }
[/code]
Тесты проходят, но не метод контроллера не считается покрытым. Попробовал другой метод :)
[code]
public PageReference NewContact(){
        PageReference page = new PageReference('/apex/CreateNewContactView');
        return page;
[/code]

[code]
@isTest static PageReference NewContact(){
        PageReference page = new PageReference('/apex/CreateNewContactView');
        return page;
[/code]

В последнем если честно вообще не понимаю как иначе можно протестировать... А ещё есть кучка методов пагинации
[code]
public PageReference Firstbtn() {
        count=0;
        getContacts();
        return null;
    }
    public PageReference prvbtn() {
        count=count-limitsize;
        getContacts();
        return null;
    }
    public PageReference Nxtbtn() {
        count=count+limitsize;
        getContacts();
        return null;
    }
    public PageReference lstbtn() {
        count = totalrecs - math.mod(totalRecs,LimitSize);
        getContacts();
        return null;
    }
    public Boolean getNxt() {
        if((count + LimitSize) > totalRecs)
            return true;
        else
            return false;   
    } 
    public Boolean getPrv() {
        if(count== 0)
            return true;
        else
            return false;
    }
[/code]
Подскажите пожалуйста как вообще подобные вещи тестируются в Salesforce. 
 

Kirill
@isTest static void Sort(){

Что-то я не увидел в тестовом методе вызов оригинального метода Sort(). Такое ощущение, что вы просто продублировали код из метода Sort().
Должно быть что-то в духе
isTest static void Sort(){
OriginalClass originalClassInstance = new OriginalClass();
originalClassInstance.OrderField = 'Name';
originalClassInstance.OrderType = ' ASC ';
originalClassInstance.Sort();
}

Т.е. задача воссоздать требуемое "окружение" (setup данных), вызвать метод, проверить правильность полученного результата.

[quote="Kirill"]@isTest static void Sort(){[/quote]
Что-то я не увидел в тестовом методе вызов оригинального метода Sort(). Такое ощущение, что вы просто продублировали код из метода Sort().
Должно быть что-то в духе 
[code]
isTest static void Sort(){
    OriginalClass originalClassInstance = new OriginalClass();
    originalClassInstance.OrderField = 'Name';
    originalClassInstance.OrderType = ' ASC ';
    originalClassInstance.Sort();
}
[/code]

Т.е. задача воссоздать требуемое "окружение" (setup данных), вызвать метод, проверить правильность полученного результата.

ilya leshchuk
Kirill
@isTest static void Sort(){

Что-то я не увидел в тестовом методе вызов оригинального метода Sort(). Такое ощущение, что вы просто продублировали код из метода Sort().
Должно быть что-то в духе
isTest static void Sort(){
OriginalClass originalClassInstance = new OriginalClass();
originalClassInstance.OrderField = 'Name';
originalClassInstance.OrderType = ' ASC ';
originalClassInstance.Sort();
}

Т.е. задача воссоздать требуемое "окружение" (setup данных), вызвать метод, проверить правильность полученного результата.

Точно... вот это я жестоко затупил ( Спасибо большое. Такой вариант работает.

@isTest static void Sort(){
ContactsManagerController controller = new ContactsManagerController();
List<String> OrderFieldValue = new List<String>();
OrderFieldValue.add('Name');
OrderFieldValue.add('Email');
OrderFieldValue.add('Contact_Level__c');
OrderFieldValue.add('AccountId');
OrderFieldValue.add('OwnerId');
OrderFieldValue.add('CreatedById');
OrderFieldValue.add('Created_Date__c');

for(Integer i=0; i<OrderFieldValue.size()-1; i++){
controller.OrderField = OrderFieldValue[i];
controller.Sort();
}
}

[quote="ilya leshchuk"][quote="Kirill"]@isTest static void Sort(){[/quote]
Что-то я не увидел в тестовом методе вызов оригинального метода Sort(). Такое ощущение, что вы просто продублировали код из метода Sort().
Должно быть что-то в духе 
[code]
isTest static void Sort(){
    OriginalClass originalClassInstance = new OriginalClass();
    originalClassInstance.OrderField = 'Name';
    originalClassInstance.OrderType = ' ASC ';
    originalClassInstance.Sort();
}
[/code]

Т.е. задача воссоздать требуемое "окружение" (setup данных), вызвать метод, проверить правильность полученного результата.[/quote]

Точно... вот это я жестоко затупил ( Спасибо большое. Такой вариант работает.
[code]
 @isTest static void Sort(){
        ContactsManagerController controller = new ContactsManagerController();
        List<String> OrderFieldValue = new List<String>();
        OrderFieldValue.add('Name');
        OrderFieldValue.add('Email');
        OrderFieldValue.add('Contact_Level__c');
        OrderFieldValue.add('AccountId');
        OrderFieldValue.add('OwnerId');
        OrderFieldValue.add('CreatedById');
        OrderFieldValue.add('Created_Date__c');
        
        for(Integer i=0; i<OrderFieldValue.size()-1; i++){
            controller.OrderField = OrderFieldValue[i];
            controller.Sort();
        }
    }[/code]

Не вижу в тесте создание тестовых данных.
Аннотация isTest отделяет тестовый код от рельных данных, вам нужно создать эти данные.
Испоьльзуйте AAA(Arrange-Act-Assert) pattern.
Сперва создайте набор контактов подходящих под ваш запрос.
Создайте StandardController и передайте туда контакт, создайте новый экземпляр контроллера или екстеншена и передайте туда StandardController. Затем вызывайте методы контроллера и сверяйте, что ожидаете и что получили по факту.

Не вижу в тесте создание тестовых данных. 
Аннотация isTest отделяет тестовый код от рельных данных, вам нужно создать эти данные.
Испоьльзуйте AAA(Arrange-Act-Assert) pattern.
Сперва создайте набор контактов подходящих под ваш запрос.
Создайте StandardController и передайте туда контакт, создайте новый экземпляр контроллера или екстеншена и передайте туда StandardController. Затем вызывайте методы контроллера и сверяйте, что ожидаете и что получили по факту. 

akr0bat
Не вижу в тесте создание тестовых данных.
Аннотация isTest отделяет тестовый код от рельных данных, вам нужно создать эти данные.
Испоьльзуйте AAA(Arrange-Act-Assert) pattern.
Сперва создайте набор контактов подходящих под ваш запрос.
Создайте StandardController и передайте туда контакт, создайте новый экземпляр контроллера или екстеншена и передайте туда StandardController. Затем вызывайте методы контроллера и сверяйте, что ожидаете и что получили по факту.

Не совсем понял... т.е. надо создать некий Class TestList в котором будут все поля которые я беру из Contact, потом заполнить его данными и вызывать по очереди метод Sort() для каждого из набора данных и потом сравнивать полученные коллекции каким-то методом Equals? Тогда мне надо будет каким-то образом отсечь дефолтные значения из Contact... получается какой-то тест на работу не метода моего, а на корректную работу DataBase.query();...
При тестировании методов типа

public PageReference prvbtn() {
count=count-limitsize;
getContacts();
return null;
Делать count =0 limitsize=10; и потом проверять стал ли Count=-10; Тут ясно, но как по мне стрельба из пушки по воробьям. Я может и ошибаюсь (на .NET делал так), тестировать нужно ж логику, а не работу арифметических операторов и запросов. Запрос может сломаться только при изменении БД, а тут уже тесты не помогут... Поправьте меня если я ошибаюсь...

[quote="akr0bat"]Не вижу в тесте создание тестовых данных. 
Аннотация isTest отделяет тестовый код от рельных данных, вам нужно создать эти данные.
Испоьльзуйте AAA(Arrange-Act-Assert) pattern.
Сперва создайте набор контактов подходящих под ваш запрос.
Создайте StandardController и передайте туда контакт, создайте новый экземпляр контроллера или екстеншена и передайте туда StandardController. Затем вызывайте методы контроллера и сверяйте, что ожидаете и что получили по факту.[/quote]

Не совсем понял... т.е. надо создать некий Class TestList в котором будут все поля которые я беру из Contact, потом заполнить его данными и вызывать по очереди метод Sort() для каждого из набора данных и потом сравнивать полученные коллекции каким-то методом Equals? Тогда мне надо будет каким-то образом отсечь дефолтные значения из Contact... получается какой-то тест на работу не метода моего, а на корректную работу DataBase.query();...
При тестировании методов типа [code] public PageReference prvbtn() {
        count=count-limitsize;
        getContacts();
        return null;[/code] Делать count =0 limitsize=10; и потом проверять стал ли Count=-10; Тут ясно, но как по мне стрельба из пушки по воробьям. Я может и ошибаюсь (на .NET делал так), тестировать нужно ж логику, а не работу арифметических операторов и запросов. Запрос может сломаться только при изменении БД, а тут уже тесты не помогут... Поправьте меня если я ошибаюсь...

akr0bat
Аннотация isTest отделяет тестовый код от рельных данных, вам нужно создать эти данные.

Смысл в том, что начиная с определенной версии apex'а если вы из тестов сделаете запрос в базу, то ничего не получите (за исключения полутора системных/конфигурационных объектов), потому что тесты по умолчанию будут выполняться в режиме seealldata=false. Т.о. если вам прям реально надо проверить работу метода, который делает запросы в базу, то сначала вам надо эту базу заполнить данными. А всё остальное уже по смыслу того что вы пытаетесь протестировать - надо вам проверить что метод с "говорящим" названием prvbtn (я так предполагаю это previous button) - засетапили данные (arrange), дёрнули метод prvbtn(act) и убедились что какая-нибудь переменная contacts, которая возможно заполняется в методе getContacts, содержит необходимый набор контактов (assert).

[quote="akr0bat"]Аннотация isTest отделяет тестовый код от рельных данных, вам нужно создать эти данные. [/quote]
Смысл в том, что начиная с определенной версии apex'а если вы из тестов сделаете запрос в базу, то ничего не получите (за исключения полутора системных/конфигурационных объектов), потому что тесты по умолчанию будут выполняться в режиме seealldata=false. Т.о. если вам прям реально надо проверить работу метода, который делает запросы в базу, то сначала вам надо эту базу заполнить данными. А всё остальное уже по смыслу того что вы пытаетесь протестировать - надо вам проверить что метод с "говорящим" названием prvbtn (я так предполагаю это previous button) - засетапили данные (arrange), дёрнули метод prvbtn(act) и убедились что какая-нибудь переменная contacts, которая возможно заполняется в методе getContacts, содержит необходимый набор контактов (assert).