0

I have an after insert trigger on a custom object which has a lookup relationship to the Opporutnity object.

When I create a new child record, the trigger fires and updates a checkbox on the Opportunity. The trigger works fine, I can test this via the UI and there are no problems.

I have just written a test class for this opportunity which does the following:

  • Creates an Opp
  • Asserts that the checkbox field is false
  • Creates a child record
  • Asserts that the checkbox field is true

(it does a bit more but this is all that's relevant)

Originally, I created a boolean variable which equalled Opporutnity.child__c, and then used this in my assertion. This failed every time.

So instead, I created a List, queried for the field and then used that in my assertion and it passed.

Does anyone know why the original assertion failed? Does this have something to do with it being an after update trigger? Or is the system just slow sometimes?

Thanks in advance

As requested, here is the code:

NOTE: this is working code. My question is why do I have to query for the data each time rather than asserting via the new opp.child__c field? Ideally I wanted to do something like: system.assert(true, oppname.child__c 'child should be true'); Thanks

Trigger:

trigger updateOppCheckbox on Bonus_Calculator__c (after insert, before delete) {        

    if (trigger.isinsert)
    {
    // Create a list of Opps to update
        List<Opportunity> oppList = new List<Opportunity>();
        system.debug('opportunity = '+ oppList);

    // Create a set of related opps
        set <id> ids = new set <id>();
        for (Bonus_Calculator__c newSet : Trigger.new)
        ids.add(newSet.opportunity__c);

    // Add child checkbox to map
        map <id,Opportunity> childMap = new map<id,Opportunity>();
        for (Opportunity o:[select child__c, bonusId__c from opportunity where id in :ids])
        childMap.put(o.id, o);

    // Loop over records and set checkbox to true
        for (Bonus_Calculator__c newBonus : Trigger.new) {

            Opportunity o = childMap.get(newBonus.opportunity__c);
            o.child__c = true;
            o.bonusId__c = newBonus.id;
            oppList.add(o);

2nd half of trigger that deals with 'if trigger is delete' has been removed for presentation purposes.

...Here is the test class

// Create Test records and delete them. Assert that checkbox is updated.    

@isTest (SeeAllData=true)
public class updateOppCheckbox_Test2 {

    static testmethod void oppCheckboxTest(){              

        // Create Opps from test utilities class
        List<Opportunity> sipOpp = testUtilities.createTestOpps(1);
        Opportunity sipOpp0 = sipOpp.get(0); 
        Integer sipOppListSize = sipOpp.size();
        system.assertEquals(1, sipOppListSize,  'sipOpp List size should be 1');

        // Check that Opp Checkbox is not checked before SIP is created
        system.assertEquals(false, sipOpp0.Child__c, 'Child__c should be false');

        // Create the SIP
        bonus_calculator__c bc1 = new bonus_calculator__c(opportunity__c = sipOpp0.Id);
        insert bc1;   

        // Query for child field
        List <Opportunity> qOpp = [SELECT Id, child__c from Opportunity where Id = :bc1.Opportunity__c];
        system.debug('qOpp =' + qOpp);
        Opportunity o = qOpp.get(0);
        boolean child = o.Child__c; 

        // Assert child__c has been updated via trigger
        system.assertEquals(true, child, 'Child should equal true');

        // Delete Bonus Record
        delete bc1;

        // Query for child field
        List <Opportunity> qOpp2 = [SELECT Id, child__c from Opportunity where Id = :bc1.Opportunity__c];
        system.debug('qOpp2 =' + qOpp2);
        Opportunity o2 = qOpp2.get(0);
        boolean child2 = o2.Child__c; 

        // Assert child__c has been updated via trigger
        system.assertEquals(false, child2, 'Child should equal false');

    }
}
  • 1
    If you post your trigger and test logic then someone should be able to help you figure out your problem. – BarCotter Dec 8 '14 at 10:50
  • Ok thanks BarCotter. I've added that now. Lets hope someone can help. Best regards – Jay Dec 8 '14 at 16:51
  • 1
    n.b. SeeAllData=true should be avoided; can lead to deployment errors and is in general not best practice and should be avoided unless the tests require sibjects that can't be created in a testmethod like (as of V32) ContentWorkspace. – cropredy Dec 8 '14 at 17:26
  • I found that I can't access records in custom settings without it enabled. Tbh I dont fully understand it and I need to read up on it asap. – Jay Dec 8 '14 at 17:31
  • your testmethods should mock the custom settings by creating the ones you need in the beginning of the testmethod (probably through a utility class as you'll no doubt be doing that across many testmethods) – cropredy Dec 8 '14 at 18:01
1

Your testmethod is way too verbose. Here is a simplified version

static testmethod void oppCheckboxTest(){              

// Create Opps from test utilities class
List<Opportunity> sipOppList = testUtilities.createTestOpps(1);
system.assertEquals(1, sipOppList.size(),  'sipOpp List size should be 1');  // you're verifying your test factory is working, probably unnecessary

// Check that Opp Checkbox is not checked before SIP is created
system.assertEquals(false, sipOppList[0].Child__c, 'Child__c should be false');

// Create the SIP
bonus_calculator__c bc1 = new bonus_calculator__c(opportunity__c = sipOppList[0].Id);
insert bc1;   

// Query for child field
List <Opportunity> oppResList = [SELECT Id, child__c from Opportunity where Id = :sipOppList[0].Id];
system.assertEquals(true, oppResList[0].child__c, 'Child should equal true');

delete bc1; // Delete Bonus Record

// Query for child field on parent Oppo
oppoResList = [SELECT Id, child__c from Opportunity where Id = :sipOppList[0].Id];

system.assertEquals(false, oppoResList[0].child__c, 'Child deleted so parent should note absence of children');
}
  • Thanks so much, I'll be the first to admit that my code isn't perfect. To give you some background, before about 3 months ago I had never written a line of apex/code. I'm a CRM manager/admin and I was asked to build a custom app to calculate people's bonuses. Consequently I had to skill up pretty fast! Anyway, thanks I've just tested this and it works great. So my question is, in your code you have put : – Jay Dec 8 '14 at 18:25
  • // Check that Opp Checkbox is not checked before SIP is created system.assertEquals(false, sipOppList[0].Child__c, 'Child__c should be false'); and then // Query for child field List <Opportunity> oppResList = [SELECT Id, child__c from Opportunity where Id = :sipOppList[0].Id]; system.assertEquals(true, oppResList[0].child__c, 'Child should equal true'); ...why is it that we can't just repeat the top line each time we want to assert and change the values and message? system.assertEquals(CHANGE, sipOppList[0].Child__c, 'Child__c should be CHANGE'); – Jay Dec 8 '14 at 18:27
  • Having to query each time seams very long winded – Jay Dec 8 '14 at 18:29
  • you have to query after each DML operation as the state of the database has changed (insert bc1, delete bc1). The first two queries simply verifies your test setup and are optional - I would not do those unless I was having trouble debugging a complex test setup – cropredy Dec 8 '14 at 20:17
  • So you're saying that oppname.child__c value just holds the value at the point in time at which it was created from the Test Utilities class. To get the up to date value we must query after each DML , right? – Jay Dec 9 '14 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.