How to write a unit-test / test class for trigger?

Apex Trigger Code Testing

  • Writing test code to invoke Apex Trigger logic is a requirement, even if you have other tests that cover other aspects of the code called from it, such as utility or library methods in other Apex classes.
  • As such you must have at least one Apex test perform the require DML operations on the object to invoke the trigger logic, no matter how little code maybe in your trigger.
  • It is common best practice these days to keep code in your Apex Trigger to a minimum and call out to another Apex class. As such it enables you to test the code in a more detailed and more focused mannor in other tests without having to setup a full data set required to issue DML requests in such tests. It also gives rise to better factoring and encapsulation as your code base grows. This consideration is popular with the TDD methodology.
  • As has already been commented you need to place test code outside of the trigger, indeed it is not actually possible to put test code in a trigger anyway.

The following is very basic illustration of the above, it strays a little into some best practices on layering and encapsulating logic around objects, but I think is relevant here, as its important to think about all logic.

Apex Class

/**
 * Class encapsulates logic relating to the Account object, 
 *   other Account related logic required by VF controllers, batch jobs etc could be placed here
 */
public with sharing class Accounts {    

    public static void onBeforeInsert(List<Account> accounts) { }
    
    public static void someOtherAccountFunctionality(List<Account> accounts) { }    
} 

Apex Trigger

trigger AccountTrigger on Account (before insert) {

    // Delegate the trigger work to an Apex class that encapsulates behavior relating to the Account object
    if(Trigger.isInsert)
        Accounts.onBeforeInsert(Trigger.new);
}

Test Class

@IsTest
private with sharing class AccountsTest {
    @IsTest
    static void testAccountTriggerViaDML()
    {
            // This example is simple, illustrates how to invoke the trigger code via DML (required), 
            //   but can become complex and detract from TDD and more granularly testing of the Accounts class
            Account testAccount = new Account( Name = 'Test Account' );
            insert testAccount;
            testAccount = [select Id, Name from Account where Id = :testAccount.Id];
            System.assertEquals(testAccount.Name, 'Test Account');  
    }
    
    @IsTest
    static void testAccountsOnInsertDirectly()
    {
            // This example is simple, but illustrates the pattern gives access to the Account class code without going via DML, 
            //   more TDD flexibility here (though must be peformed in conjunction with the above style tests as well)
            Account testAccount = new Account( Name = 'Test Account' );
            Accounts.onBeforeInsert(new List<Account> { testAccount } );
            System.assertEquals(testAccount.Name, 'Test Account');
    }

    @IsTest
    static void testSomeOtherAccountFunctionality()
    {
            // Test a specific method on the Accounts class (this may also be tested via the tests associated with the logic calling it
            //     however in a TDD approach these tests still have a role to test such methods in more detail)
            Account testAccount = new Account( Name = 'Test Account' );
            Accounts.testSomeOtherAccountFunctionality(new List<Account> { testAccount });
            System.assertEquals(testAccount.Name, 'Test Account');
    }
}

You can write test methods in two different ways one is in same class and the other one is to write the test methods in separate class the first method is only applicable for the Apex classes having Api version 27 or earlier and the second one is to write test methods in a separate class which is also a good practice please visit http://forcespider.wordpress.com/ for more details.


http://blogs.developerforce.com/engineering/2013/04/apex-test-code-segregation.html

Here is the recent blog post from Josh Kaplan (Product Manager for APEX).Starting with the Summer ’13 release of the platform, Apex test methods need to be created in test classes.This change will make Testing efficient.Various reasons are clearly documented why we need different class in the above blog.