This is a very interesting scenario, which everyone faced while testing/deploying omnichannel. Inserting is not allowed and as manish porwal suggested you have to make test running user as active on OmniChannel to get coverage for AgentWorkTrigger. This makes unit testing hard and impossible for CI/CD as someone has to manually go and make test running user as active to test class to pass.
So the requirement boils down to:
1) How to achieve some coverage on AgentWork
Trigger?
2) How to unitest them without inserting then?
The logic lies in beforeInsert trigger, consider the order of execution:
The key point to note here is, in insert the before insert trigger runs first and then the system validation steps.
The exception you mentioned:
: Insert failed. First exception on row 0; first error:
FIELD_INTEGRITY_EXCEPTION, The agent's status is not associated with
the channel for this work.: [ServiceChannelId]
happens after the before insert trigger, thus if you catch that, you can have some coverage in trigger thus it can be deployed without making any user as active in OmniChannel.
Things get simpler if you write a single line trigger and make your handler do everything:
trigger AgentWorkTrigger on AgentWork (before insert, after update) {
AgentWorkTriggerHandler.run();
}
public class AgentWorkTriggerHandler{
public static void run(){
switch on Trigger.operationType {
when BEFORE_INSERT {
System.debug('Before Insert'); //For Test
}
when AFTER_UPDATE {
agentWorkService.doMyLogic(Trigger.new);//Your Service method
}
}
}
}
Now to test trigger for coverage
@isTest
private static testTriggerCoverage(){
ServiceChannel sc = [SELECT Id
FROM ServiceChannel WHERE DeveloperName = 'TestUnit'
LIMIT 1];
Case caseRec = [SELECT Id FROM Case LIMIT 1];
User systemUser = [SELECT Id FROM User WHERE FirstName = 'System'];
System.runAs(systemUser){
//Try Catch is to ensure test doesn't fail in cisit and ciuat
try{
AgentWork aw = new AgentWork(
ServiceChannelId = sc.Id,
WorkItemId = caseRec.Id,
UserId = systemUser.Id
);
insert aw;
aw.MyField__c = 'Submitted';
update aw;
}catch(Exception ex){
//Exception will occur due to the omni channel bug. Ignore it
}
}
Here, I am catching the exception to have some coverage for AgentTrigger
Now you code logic now exists in Handlers/Service methods, thus you can mock Trigger.new, old, newMap,Oldmap and send it to your service methods and get them covered.
Resources: https://developer.salesforce.com/forums/?id=906F00000005KVYIA2