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

Unit Test для триггера

Создал триггер для обращения к внешнему ресурсу

Триггер:

trigger CreativeRequestRemoteUpdate on Creative_Request__c (after insert, after update, after delete) {

String action;
Set<Id> crreqIds = new Set<Id>();

if (Trigger.isInsert) { action = 'insert'; crreqIds = Trigger.newMap.keySet(); }
if (Trigger.isUpdate) { action = 'update'; crreqIds = Trigger.newMap.keySet(); }
if (Trigger.isDelete) { action = 'delete'; crreqIds = Trigger.oldMap.keySet(); }

CreativeRequest_TriggerHelperNTM.updateCreativeRequest(action, crreqIds);
}

Класс:

public with sharing class CreativeRequest_TriggerHelperNTM {

@future (callout=true)
public static void updateCreativeRequest (String action, Set<Id> crreqSetIds) {

List<Id> crreqListIds = new List<Id>(crreqSetIds);
String ids = String.join(crreqListIds, ',');

HttpRequest req = new HttpRequest();
req.setEndpoint('http://test.com/sf/remote/sf_query_1&token=fgkgwkugfwiuegf&act='+action+'&ids='+ids);
req.setMethod('GET');

Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());
}
}

При деплое на продакшин пишет что методы недостаточно покрыты тестом.
Читал Вашу статью http://salesforce-developer-rus.blogspot.com/2013/01/testing-apex-code.html
Но не понимаю как писать юнит тест в моем случае

Полагаю что начинать надо так:

@isTest
private static void testNtmTriggers() {

}

Нужно ли мне создавать юзера в тесте, возможно нет

Ну вобщем думаю что как то так:

@isTest
private static void testNtmTriggers() {
// подготовка данных для тестирования
test.startTest();
// непосредственно тестирование (вызов методов, проверка возвращаемых данных)
test.stopTest();
}

Мне не очевидно какие данные готовить для тестирования и как вызывать сам тестируемый метод

Snn
Создал триггер для обращения к внешнему ресурсу

Триггер:
[code]
trigger CreativeRequestRemoteUpdate on Creative_Request__c (after insert, after update, after delete) {

    String action;
    Set<Id> crreqIds = new Set<Id>();

    if (Trigger.isInsert) { action = 'insert'; crreqIds = Trigger.newMap.keySet(); }
    if (Trigger.isUpdate) { action = 'update'; crreqIds = Trigger.newMap.keySet(); }
    if (Trigger.isDelete) { action = 'delete'; crreqIds = Trigger.oldMap.keySet(); }

    CreativeRequest_TriggerHelperNTM.updateCreativeRequest(action, crreqIds);
}
[/code]

Класс:
[code]
public with sharing class CreativeRequest_TriggerHelperNTM {

    @future (callout=true)
    public static void updateCreativeRequest (String action, Set<Id> crreqSetIds) {

        List<Id> crreqListIds = new List<Id>(crreqSetIds);
        String ids = String.join(crreqListIds, ',');

        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://test.com/sf/remote/sf_query_1&token=fgkgwkugfwiuegf&act='+action+'&ids='+ids);
        req.setMethod('GET');

        Http http = new Http();
        HTTPResponse res = http.send(req);
        System.debug(res.getBody());
    }
}
[/code]

При деплое на продакшин пишет что методы недостаточно покрыты тестом.
Читал Вашу статью [url]http://salesforce-developer-rus.blogspot.com/2013/01/testing-apex-code.html[/url]
Но не понимаю как писать юнит тест в моем случае

Полагаю что начинать надо так:
[code]
    @isTest
    private static void testNtmTriggers() {
        
    }
[/code]
Нужно ли мне создавать юзера в тесте, возможно нет

Ну вобщем думаю что как то так:
[code]
    @isTest
    private static void testNtmTriggers() {
        // подготовка данных для тестирования  
        test.startTest();  
        // непосредственно тестирование (вызов методов, проверка возвращаемых данных)  
        test.stopTest();
    }
[/code]

Мне не очевидно какие данные готовить для тестирования и как вызывать сам тестируемый метод

Все очень просто. Чтобы покрыть триггер тестами надо инициировать запуск триггера.

Триггер запускается в результате работы DML операции (insert, update, delete, upsert)

Вот что надо сделать по шагам:
1. Создаем класс с названием по смыслу (например SomeTriggerTest.cls)
2. берем мой шаблон как есть (меняем только HelloTests на SomeTriggerTest):

@isTest  
private class HelloTests {
static testMethod void Test1() {
Profile profile = [select id, Name from profile where name='System Administrator'];
User user = new User(alias = 'tt01', email='testtest01@test.com', emailencodingkey='UTF-8', lastname='testtest01', languagelocalekey='en_US', localesidkey='en_US', profileid = profile.Id, timezonesidkey='America/Los_Angeles', username='testtest01@test.com');
insert user;
System.RunAs(user){
// подготовка данных для тестирования
test.startTest();
// непосредственно тестирование (вызов методов, проверка возвращаемых данных)
test.stopTest();
}
}
}

3. В подготовку данных пока ничего не пишем ()
4. В "непосредственно тестирование" будем заносит все наше тестирование:
т.к. у нас в триггере указано что "on Creative_Request__c (after insert, after update, after delete)" то нужно инициировать три DML операции.
вот примерно что должно получиться в секции между test.startTest() и test.stopTest() (пишу напрямую без проверки компилятором, так что могут быть ошибки но нам главное уловить смысл):

Creative_Request__c obj = new Creative_Request__c (Name = 'Some name');
insert obj;
update obj;
delete ojb;

Собственно весь тест метод.

Все очень просто. Чтобы покрыть триггер тестами надо инициировать запуск триггера.

Триггер запускается в результате работы DML операции (insert, update, delete, upsert)

Вот что надо сделать по шагам:
1. Создаем класс с названием по смыслу (например SomeTriggerTest.cls)
2. берем мой шаблон как есть (меняем только HelloTests  на SomeTriggerTest):
[code]@isTest  
 private class HelloTests {  
      static testMethod void Test1() {  
           Profile profile = [select id, Name from profile where name='System Administrator'];  
           User user = new User(alias = 'tt01', email='testtest01@test.com', emailencodingkey='UTF-8', lastname='testtest01', languagelocalekey='en_US', localesidkey='en_US', profileid = profile.Id, timezonesidkey='America/Los_Angeles', username='testtest01@test.com');  
           insert user;  
           System.RunAs(user){  
               // подготовка данных для тестирования  
               test.startTest();  
               // непосредственно тестирование (вызов методов, проверка возвращаемых данных)  
               test.stopTest();  
           }  
      }  
 } [/code]

3. В подготовку данных пока ничего не пишем ()
4. В "непосредственно тестирование" будем заносит все наше тестирование:
т.к. у нас в триггере указано что "on Creative_Request__c (after insert, after update, after delete)" то нужно инициировать три DML операции.
вот примерно что должно получиться в секции между test.startTest() и test.stopTest() (пишу напрямую без проверки компилятором, так что могут быть ошибки но нам главное уловить смысл):

Creative_Request__c obj = new Creative_Request__c (Name = 'Some name');
insert obj;
update obj;
delete ojb;

Собственно весь тест метод.

Теперь еще одно замечание:

при каждой DML операции в тест методе у тебя будет вызываться
CreativeRequest_TriggerHelperNTM.cls (future метод updateCreativeRequest)

В нем есть такая строчка
HTTPResponse res = http.send(req);
Это обращение к внешнему сервису.

В тест методах на этой строчке получишь исключение.

Чтобы тесты отработали без ошибок надо последние две строчки заменить на следующие:

if (!test.isRunnungTest){
HTTPResponse res = http.send(req);
System.debug(res.getBody());
}

Теперь еще одно замечание:

при каждой DML операции в тест методе у тебя будет вызываться 
CreativeRequest_TriggerHelperNTM.cls (future метод updateCreativeRequest)

В нем есть такая строчка
HTTPResponse res = http.send(req);
Это обращение к внешнему сервису.

В тест методах на этой строчке получишь исключение.

Чтобы тесты отработали без ошибок надо последние две строчки заменить на следующие:

[code]if (!test.isRunnungTest){
     HTTPResponse res = http.send(req);
     System.debug(res.getBody());
}[/code]

Рабочий юнит тест:

@isTest
private class CreativeRequest_TriggerHelperNTM_Tests {
static testMethod void Test1() {
Profile profile = [select id, Name from profile where name='System Administrator'];
User user = new User(alias = 'tt01', email='testtest01@test.com', emailencodingkey='UTF-8', lastname='testtest01', languagelocalekey='en_US', localesidkey='en_US', profileid = profile.Id, timezonesidkey='America/Los_Angeles', username='testtest01@test.com');
insert user;
System.RunAs(user){
test.startTest();

Project__c obj_project = new Project__c (Name = 'test');
insert obj_project;

Creative_Request__c obj = new Creative_Request__c (Name = 'test', Project__c = obj_project.Id, Completion_Time__c = DateTime.now());
insert obj;
update obj;
delete obj;

test.stopTest();
}
}
}

Спасибо

Snn
Рабочий юнит тест:

[code]
@isTest
private class CreativeRequest_TriggerHelperNTM_Tests {
    static testMethod void Test1() {
        Profile profile = [select id, Name from profile where name='System Administrator'];
        User user = new User(alias = 'tt01', email='testtest01@test.com', emailencodingkey='UTF-8', lastname='testtest01', languagelocalekey='en_US', localesidkey='en_US', profileid = profile.Id, timezonesidkey='America/Los_Angeles', username='testtest01@test.com');
        insert user;
        System.RunAs(user){
            test.startTest();

            Project__c obj_project = new Project__c (Name = 'test');
            insert obj_project;

            Creative_Request__c obj = new Creative_Request__c (Name = 'test', Project__c = obj_project.Id, Completion_Time__c = DateTime.now());
            insert obj;
            update obj;
            delete obj;

            test.stopTest();
        }
    }
}
[/code]

Спасибо