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

Оптимизация класса для тестирования

Добрый день. Задача следующая: имеется три связанных объекта Student__c ,Participation__c, Course__c. Student__c<-->Participation__c связь master-detail,Participation__c<-->Course__c связь lookup. Как написать вспомогательны класс Фабрику для тестирования возвращающий список с 3мя связанными объектами без операции insert?
Вот что у меня получилось:

public class FactoryForTest {

public static void setData(Integer count, Decimal HoursAttended, Decimal Duration, String grade, String result) {

List < Student__c > studentList = new List < Student__c > ();
List < Course__c > courseList = new List < Course__c > ();
List < Participation__c > participationList = new List < Participation__c > ();

for (Integer i = 0; i < count; i++) {

studentList.add(new Student__c(First_Name__c = 'TestFName' + i, Last_Name__c = 'TestLName' + i));
}
insert studentList;
for (Integer i = 0; i < count; i++) {
courseList.add(new Course__c(Duration__c = Duration, Name__c = 'TestCourse' + i));
}
insert courseList;

for (Integer i = 0; i < count; i++) {
participationList.add(new Participation__c(Student__c = studentList.get(i).Id,
Course__c = courseList.get(i).Id, Hours_attended__c = Hoursattended, Grade__c = grade, Result__c = result));
}
insert participationList;
}


}


Можно написать геттеры для 3 List, но как их связать без операции insert?

Добрый день. Задача следующая: имеется три связанных объекта Student__c ,Participation__c, Course__c. Student__c<-->Participation__c  связь master-detail,Participation__c<-->Course__c связь lookup.  Как написать вспомогательны класс Фабрику для тестирования возвращающий список с 3мя связанными объектами без операции insert? 
Вот что у меня получилось:
[code]
public class FactoryForTest {
 
  public static void setData(Integer count, Decimal HoursAttended, Decimal Duration, String grade, String result) {

    List < Student__c > studentList = new List < Student__c > ();
    List < Course__c > courseList = new List < Course__c > ();
    List < Participation__c > participationList = new List < Participation__c > ();

    for (Integer i = 0; i < count; i++) {

      studentList.add(new Student__c(First_Name__c = 'TestFName' + i, Last_Name__c = 'TestLName' + i));
    }
    insert studentList;
    for (Integer i = 0; i < count; i++) {
      courseList.add(new Course__c(Duration__c = Duration, Name__c = 'TestCourse' + i));
    }
    insert courseList;

    for (Integer i = 0; i < count; i++) {
      participationList.add(new Participation__c(Student__c = studentList.get(i).Id,
        Course__c = courseList.get(i).Id, Hours_attended__c = Hoursattended, Grade__c = grade, Result__c = result));
    }
    insert participationList;
  }


}

[/code]
Можно написать геттеры для 3 List, но как их связать без операции insert?

Что-то вопрос не понятен. Что значит без insert. Принцип тестов - создать тестовые данные в базе данных и запустить методы для тестирования. Нафига такие извращения? Что-то Java стало попахивать. Если так, то выкинут этим модные паттерны из головы и делать как написано в документации по SF. Все эти излишние оптимизации ни к чему кроме усложнения проекта и потери времени не приводят.

Что-то вопрос не понятен. Что значит без insert. Принцип тестов - создать тестовые данные в базе данных и запустить методы для тестирования. Нафига такие извращения? Что-то Java стало попахивать. Если так, то выкинут этим модные паттерны из головы и делать как написано в документации по SF. Все эти излишние оптимизации ни к чему кроме усложнения проекта и потери времени не приводят.

Начните с декомпозиции Ваших макарон(3 объекта в одном методе) в setData().
Как будто бы без инсерта - есть UOW, но для такого теста это избыточно.

Начните с декомпозиции Ваших макарон(3 объекта в одном методе) в setData(). 
Как будто бы без инсерта - есть UOW, но для такого теста это избыточно.

Ок. На счет сложности согласен, но мучает любопытство.Задам ворос по другому: как создать три связанных объекта без операции Insert. Можно ли получить Id объекта, необходимый для создания связанных объектов, без операции insert?

Ок. На счет сложности согласен, но мучает любопытство.Задам ворос по другому: как создать три связанных объекта без операции Insert. Можно ли получить Id объекта, необходимый для создания связанных объектов, без операции insert? 

Eugene Konstantinof
Начните с декомпозиции Ваших макарон(3 объекта в одном методе) в setData().
Как будто бы без инсерта - есть UOW, но для такого теста это избыточно.

Ок создам 3 геттера возвращающие списки с созданными объектами. Как сделать чтобы эти три объекта были связаны между собой? Где подробнее можно прочитать про UOW?

[quote="Eugene Konstantinof"]Начните с декомпозиции Ваших макарон(3 объекта в одном методе) в setData(). 
Как будто бы без инсерта - есть UOW, но для такого теста это избыточно.[/quote]
Ок создам 3 геттера возвращающие списки с созданными объектами. Как сделать чтобы эти три объекта были связаны между собой? Где подробнее можно прочитать про UOW?

Id без insert нельзя получить ни задать вручную.

А можно чисто для расширения своего опыта узнать первоисточник данного вопроса? Зачем это нужно делать?

Id без insert нельзя получить ни задать вручную. 

А можно чисто для расширения своего опыта узнать первоисточник данного вопроса? Зачем это нужно делать? 

Я хотел узнать как правильно написать вспомогательный класс фабрику для тестирования кода. Овет получен, вопрос закрыт. Спасибо.

Я хотел узнать как правильно написать вспомогательный класс фабрику для тестирования кода.   Овет получен, вопрос закрыт. Спасибо.

Всё зависит от того какая связь вам нужна, если это child-to-parent тут всё просто:

Account accountA = new Account(Name = 'Account A');
Opportunity opportunityA = new Opportunity(Name = 'Opportunity A', Account = accountA);

System.debug(opportunityA.Account);

а если надо наоборот parent-to-child тут надо немножко схитрить - например получите из базы несколько интересующих вас данных через execute anonymous, засериализируйте в JSON, посмотрите что у вас получится и идите от обратного, например вот так:

Account accountB = (Account) System.JSON.deserialize('{"Name": "Account B","Opportunities":{"records":[{"Name":"Opportunity B"}], "done": true, "totalSize":1}}', Account.class);

System.debug(accountB.Opportunities);

Dmitry Shnyrev
Id без insert нельзя получить ни задать вручную.

А можно чисто для расширения своего опыта узнать первоисточник данного вопроса? Зачем это нужно делать?


Строго говоря это не совсем так - можно получить instance типа id "из воздуха", но с другой стороны зачем это надо и какая от этого практическая польза:
String someID = SObjectType.Account.keyPrefix + '000000000000000';//some keyPrefix and 15 zeroes
System.debug(someID instanceof Id);

Всё зависит от того какая связь вам нужна, если это child-to-parent тут всё просто:
[code]
Account accountA = new Account(Name = 'Account A');
Opportunity opportunityA = new Opportunity(Name = 'Opportunity A', Account = accountA);

System.debug(opportunityA.Account);
[/code]

а если надо наоборот parent-to-child тут надо немножко схитрить - например получите из базы несколько интересующих вас данных через execute anonymous, засериализируйте в JSON, посмотрите что у вас получится и идите от обратного, например вот так:
[code]
Account accountB = (Account) System.JSON.deserialize('{"Name": "Account B","Opportunities":{"records":[{"Name":"Opportunity B"}], "done": true, "totalSize":1}}', Account.class);

System.debug(accountB.Opportunities);
[/code]

[quote="Dmitry Shnyrev"]Id без insert нельзя получить ни задать вручную. 

А можно чисто для расширения своего опыта узнать первоисточник данного вопроса? Зачем это нужно делать?[/quote]
Строго говоря это не совсем так - можно получить instance типа id "из воздуха", но с другой стороны зачем это надо и какая от этого практическая польза:
[code]
String someID = SObjectType.Account.keyPrefix + '000000000000000';//some keyPrefix and 15 zeroes
System.debug(someID instanceof Id);
[/code]


Вариант с десериализацией огонь! Что-то мне в голову не пришло, хотя использовали и не раз на проектах для подготовки Mock данных

[img]https://az705183.vo.msecnd.net/onlinesupportmedia/onlinesupport/media/skype/fa300xx/like_40x40.gif[/img]
Вариант с десериализацией огонь! Что-то мне в голову не пришло, хотя использовали и не раз на проектах для подготовки Mock данных :( 

если тебе нужно было ID только для того чтобы связать между собой Parent и Child то вместо ID можно использовать ExternalID (загвоздка - для этого надо иметь ExternalID)
зато работает хорошо в тестах
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_nested_object.htm

если тебе нужно было ID только для того чтобы связать между собой Parent и Child то вместо ID можно использовать ExternalID (загвоздка - для этого надо иметь ExternalID)
зато работает хорошо в тестах
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_nested_object.htm