我正在为Email触发器编写测试类。根据New frame的工作,我们修改了触发器,并为该触发器创建了处理程序类。 所有这些方法都失败了,我在运行测试类时遇到了这些错误。 System.NullPointerException:尝试取消引用空对象 Class.Email_TriggerHandler.getTriggerEvent:第152行,第1列 Class.Email_TriggerHandler.addToLoopCount:第135行,第1列 Class.Email_TriggerHandler.run:第35行,第1列 Class.Email_TriggerHandler_Test.testAfterDelete:第56行,第1列
@isTest
private class Email_TriggerHandler_Test {
private static final String TRIGGER_CONTEXT_ERROR = 'Trigger handler called outside of Trigger execution';
private static String lastMethodCalled;
private static Email_TriggerHandler_Test.TestHandler handler;
static {
handler = new Email_TriggerHandler_Test.TestHandler();
// override its internal trigger detection
handler.isTriggerExecuting = true;
}
/***************************************
* unit tests
***************************************/
// contexts tests
@isTest
static void testBeforeInsert() {
beforeInsertMode();
handler.run();
System.assertEquals('beforeInsert', lastMethodCalled, 'last method should be beforeInsert');
}
@isTest
static void testBeforeUpdate() {
beforeUpdateMode();
handler.run();
System.assertEquals('beforeUpdate', lastMethodCalled, 'last method should be beforeUpdate');
}
@isTest
static void testBeforeDelete() {
beforeDeleteMode();
handler.run();
System.assertEquals('beforeDelete', lastMethodCalled, 'last method should be beforeDelete');
}
@isTest
static void testAfterInsert() {
afterInsertMode();
handler.run();
System.assertEquals('afterInsert', lastMethodCalled, 'last method should be afterInsert');
}
@isTest
static void testAfterUpdate() {
afterUpdateMode();
handler.run();
System.assertEquals('afterUpdate', lastMethodCalled, 'last method should be afterUpdate');
}
@isTest
static void testAfterDelete() {
afterDeleteMode();
handler.run();
System.assertEquals('afterDelete', lastMethodCalled, 'last method should be afterDelete');
}
@isTest
static void testAfterUndelete() {
try{
afterUndeleteMode();
handler.run();
//System.assertEquals('afterUndelete', lastMethodCalled, 'last method should be afterUndelete');
}
catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
System.assertEquals(TRIGGER_CONTEXT_ERROR, te.getMessage(), 'the exception message should match');
} catch(Exception e) {
//System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
}
@isTest
static void testNonTriggerContext() {
try{
handler.run();
System.assert(false, 'the handler ran but should have thrown');
} catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
System.assertEquals(TRIGGER_CONTEXT_ERROR, te.getMessage(), 'the exception message should match');
} catch(Exception e) {
System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
}
// test bypass api
@isTest
static void testBypassAPI() {
afterUpdateMode();
// test a bypass and run handler
Email_TriggerHandler.bypass('TestHandler');
handler.run();
System.assertEquals(null, lastMethodCalled, 'last method should be null when bypassed');
System.assertEquals(true, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
// clear that bypass and run handler
Email_TriggerHandler.clearBypass('TestHandler');
handler.run();
System.assertEquals('afterUpdate', lastMethodCalled, 'last method called should be afterUpdate');
System.assertEquals(false, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
// test a re-bypass and run handler
Email_TriggerHandler.bypass('TestHandler');
handler.run();
System.assertEquals(null, lastMethodCalled, 'last method should be null when bypassed');
System.assertEquals(true, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
// clear all bypasses and run handler
Email_TriggerHandler.clearAllBypasses();
handler.run();
System.assertEquals('afterUpdate', lastMethodCalled, 'last method called should be afterUpdate');
System.assertEquals(false, Email_TriggerHandler.isBypassed('TestHandler'), 'test handler should be bypassed');
resetTest();
}
// instance method tests
@isTest
static void testLoopCount() {
beforeInsertMode();
// set the max loops to 2
handler.setMaxLoopCount(2);
// run the handler twice
handler.run();
handler.run();
// clear the tests
resetTest();
try {
// try running it. This should exceed the limit.
handler.run();
System.assert(false, 'the handler should throw on the 3rd run when maxloopcount is 3');
} catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
// we're expecting to get here
System.assertEquals(null, lastMethodCalled, 'last method should be null');
} catch(Exception e) {
System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
// clear the tests
resetTest();
// now clear the loop count
handler.clearMaxLoopCount();
try {
// re-run the handler. We shouldn't throw now.
handler.run();
System.assertEquals('beforeInsert', lastMethodCalled, 'last method should be beforeInsert');
} catch(Email_TriggerHandler.ICS_TriggerHandlerException te) {
System.assert(false, 'running the handler after clearing the loop count should not throw');
} catch(Exception e) {
System.assert(false, 'the exception thrown was not expected: ' + e.getTypeName() + ': ' + e.getMessage());
}
}
@isTest
static void testLoopCountClass() {
Email_TriggerHandler.LoopCount lc = new Email_TriggerHandler.LoopCount();
System.assertEquals(5, lc.getMax(), 'max should be five on init');
System.assertEquals(0, lc.getCount(), 'count should be zero on init');
lc.increment();
System.assertEquals(1, lc.getCount(), 'count should be 1');
System.assertEquals(false, lc.exceeded(), 'should not be exceeded with count of 1');
lc.increment();
lc.increment();
lc.increment();
lc.increment();
System.assertEquals(5, lc.getCount(), 'count should be 5');
System.assertEquals(false, lc.exceeded(), 'should not be exceeded with count of 5');
lc.increment();
System.assertEquals(6, lc.getCount(), 'count should be 6');
System.assertEquals(true, lc.exceeded(), 'should not be exceeded with count of 6');
}
// private method tests
@isTest
static void testGetHandlerName() {
System.assertEquals('TestHandler', handler.getHandlerName(), 'handler name should match class name');
}
// test virtual methods
@isTest
static void testVirtualMethods() {
Email_TriggerHandler h = new Email_TriggerHandler();
h.beforeInsert();
h.beforeUpdate();
h.beforeDelete();
h.afterInsert();
h.afterUpdate();
h.afterDelete();
h.afterUndelete();
}
/***************************************
* testing utilities
***************************************/
private static void resetTest() {
lastMethodCalled = null;
}
// modes for testing
private static void beforeInsertMode() {
handler.setTriggerContext('before insert', true);
}
private static void beforeUpdateMode() {
handler.setTriggerContext('before update', true);
}
private static void beforeDeleteMode() {
handler.setTriggerContext('before delete', true);
}
private static void afterInsertMode() {
handler.setTriggerContext('after insert', true);
}
private static void afterUpdateMode() {
handler.setTriggerContext('after update', true);
}
private static void afterDeleteMode() {
handler.setTriggerContext('after delete', true);
}
private static void afterUndeleteMode() {
handler.setTriggerContext('after undelete', true);
}
// test implementation of the Email_TriggerHandler
private class TestHandler extends Email_TriggerHandler {
public override void beforeInsert() {
Email_TriggerHandler_Test.lastMethodCalled = 'beforeInsert';
}
public override void beforeUpdate() {
Email_TriggerHandler_Test.lastMethodCalled = 'beforeUpdate';
}
public override void beforeDelete() {
Email_TriggerHandler_Test.lastMethodCalled = 'beforeDelete';
}
public override void afterInsert() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterInsert';
}
public override void afterUpdate() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterUpdate';
}
public override void afterDelete() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterDelete';
}
public override void afterUndelete() {
Email_TriggerHandler_Test.lastMethodCalled = 'afterUndelete';
}
}
}