Как получить покрытие кода, необходимое для развертывания класса Apex

Пожалуйста помоги!!! У меня есть класс контроллера Apex, который я пытаюсь развернуть из песочницы Salesforce в производственную среду, но я не получаю требуемого покрытия кода !!

класс потребляет 3 объекта, один - многопользовательский, а 2 - пользовательские, и строит иерархическое древовидное представление для этих трех объектов.

// Класс Apex

public class TeeView {

        /* Wrapper class to contain the nodes and their children */
 public class cNodes
{
    Public StandardObject gparent {get;set;}
    public List<CustomObject1__c> parent {get; set;}
    Public List<CustomObject2__c> child {get;set;}

    public cNodes(StandardObject   gp, List<CustomObject1__c> p, List<CustomObject2__c> c)
    {
    parent = p;
    gparent = gp;
    child = c;
    }
}

        /* end of Wrapper class */ 

Public List<cNodes> hierarchy;

Public List<cNodes> getmainnodes()
{
    hierarchy = new List<cNodes>();
    List<StandardObject> tempparent = [Select Id,Name  , End_Date__c, Owner.Name Account.Name from Contract ];
    for (Integer i =0; i< tempparent.size() ; i++)
        {
        List<CustomObject1__c> tempchildren = [Select Id,Name, Owner.Name , (select Id,Name, Owner.Name from CustomObject2__r)  from CustomObject1__c where    Related_Field__c = :tempparent[i].Id];
        List<CustomObject2__c> tempchild = [Select Id,Name Owner.Name from CustomObject2__c where    Related_Field__c= :tempparent[i].Id];

        hierarchy.add(new cNodes(tempparent[i],tempchildren, tempchild));
        }   
    return hierarchy;
}  

}

// Тестовый класс @isTest общедоступный класс treeviewTest {

static testMethod void test1()
{
    test.startTest();


    Account acc = new Account(Name = 'Unit test account');
    insert acc;

    StandardObject c = new StandardObject(
        Name = 'test',
        AccountId = acc.Id,
        Status = 'Draft',
        StartDate = System.today());
    try
    {
        insert c;
    }
    catch (Exception ex)
    {
        ApexPages.addMessages(ex);
    }

    List<StandardObject> standard = [select Id, Name from StandardObject where Name = 'test'];
    system.assertequals(standard.size(), 1);

    CustomObject1__c s = new CustomObject1__c(
        Related_StandardObjectField__c = c.Id,
        Name = 'test'
    );
    try
    {
        insert s;
    }
    catch (Exception ex)
    {
        ApexPages.addMessages(ex);
    }

    List<CustomObject1__c> cus1 = [select Id, Name from CustomObject1__c where Name = 'test'];
    system.assertequals(cus1.size(), 1);

    insert new CustomObject2__c(Related_StandardObjectField__c = c.Id, Description__c = 'test');
    List<CustomObject2__c> cus2 = [select Id, Name from CustomObject2__c where Description__c = 'test'];
    system.assertequals(cus2.size(), 1);

    insert new CustomObject2__c(Related_CustomObject1Field__c = s.Id, Description__c = 'test');
    List<Mods__c> cus3 = [select Id, Name from Mods__c where Description__c = 'test'];
    system.assertequals(cus3.size(), 1);

    treeView view = new treeView();

    view.getmainnodes();


    test.stopTest();
}

}


person Lee Jones    schedule 30.09.2017    source источник


Ответы (2)


Ой, с чего бы нам вообще начать ... Похоже, вы скопировали какой-то код наугад, пытаясь заставить тест работать? Ваш код работает на Contract, CustomObject1__c, CustomObject2__c. Ваш модульный тест вставляет Contract, Subaward__c, Mods__c. Была ли это попытка анонимизировать ваш код? И что это за List<StandardObject> штука, она даже не должна компилироваться.

Я думаю, вам нужна помощь разработчика с большим опытом, вы что-то сколотили вместе, но это не соответствует лучшим практикам Salesforce для кода ...

Об основном классе

Разумное использование подзапросов будет означать

  • вы тратите меньше SOQL (плохая идея слепо выбирать все записи без каких-либо фильтров, но неважно),
  • не сталкиваться с ошибками, связанными с "слишком большим количеством операторов SOQL" (предел равен 100, поэтому, поскольку вы запрашиваете в цикле, ваш код выйдет из строя и сгорит в тот момент, когда у вас будет около 50 контрактов)
  • приводят к компактному коду, занимающему меньше строк (легче поддерживать и покрывать тестами).

Я бы пошел с чем-то вроде этого, запросил контракт и первый связанный список за один раз, а затем родители + дети в другом запросе. Использование Map, чтобы связать их для отображения.

List<Contract> levelOneAndTwo = [SELECT Id, Name, End_Date__c, Owner.Name, Account.Name,
    (SELECT Id,Name, Owner.Name FROM Subawards__r)
FROM Contract];

Map<Id, SubAward__c> levelTwoAndThree = new Map<Id, Subaward__c>([SELECT Id,
    (SELECT Id,Name Owner.Name FROM Mods__r)
    FROM Subaward__c WHERE Contract__c = :levelOneAndTwo];
);

Это тратит только 2 запроса, но извлекает все контракты и связанные с ними данные. Затем вы можете перебрать результаты, создавая объект-оболочку, или просто передать его непосредственно в Visualforce для отображения.

О модульном тесте

Вы не получаете покрытия, потому что вы слишком тонко растеклись. Один метод модульного тестирования вставляет только контракты (так что ваш основной запрос что-то ударит, даст вам некоторое покрытие). Затем другой метод (в совершенно другом контексте) вставляет некоторые дочерние объекты - но они не имеют значения. В этом другом методе нет контрактов, поэтому он даже не войдет в ваш основной цикл. Объединить в одно?

Account acc = new Account(Name = 'Unit test account');
insert acc;

Contract c = new Contract(
    Name = 'test contract',
    AccountId = acc.Id,
    Status = 'Draft',
    StartDate = System.today()
);
insert c;

Subaward__c s = new Subaward(
    Contract__c = c.Id,
    Name = 'test'
);
insert s;

insert new Mod__c(Subaward__c = c.Id, Description__c = 'test');

Теперь у вас настроена хорошая древовидная иерархия, от учетной записи до конца. Запросы в тесте должны попадать в некоторые данные.

person eyescream    schedule 30.09.2017

Я наконец смог получить 100% покрытие кода для вышеуказанного класса, добавив следующие строки в тестовый класс:

     treeView view = new treeView();
                view.getmainnodes();
                    system.assert(view.hierarchy.size() > 0); 
person Lee Jones    schedule 30.09.2017