I have an Apex trigger on Opportunity objects that is fired after insert. When the opportunity is inserted, I want to update a date-type field, Pipeline_Start__c, in the Account to which the Opportunity belongs to. The problem is that when I run my tests, the Pipeline_Start__c field is always null. Here is the trigger

trigger OpportunityTrigger on Opportunity (after insert) {
    List<String> emails = new List<String>();
    for (Opportunity opp : Trigger.new) {
        Account acc = [select PersonEmail from Account where id=:opp.AccountId];
        acc.Pipeline_Start__c = Date.today();
        update acc;

Updating to show unit test

private static void TestCreateOpp() {
    Account acc = new Account(
    insert acc;

    Test.setMock(HttpCallOutMock.class, new CalloutMock());
    Opportunity opp = new Opportunity(
    insert opp;

    System.debug(acc); // Prints out Firstname, Lastname, PersonEmail and Id, NOT Pipeline_Start__c
    System.assertEquals(acc.Pipeline_Start__c, Date.today());
  • 2
    Never ever use a query in a for loop. Even if you haven't gotten to logic-less triggers, that's an absolute must to understand before pushing any triggers into a live environment. That said, we need to see your test before knowing why it fails. – Adrian Larson Mar 12 '18 at 16:38
  • Even if there can only be one result from the query? – Briscoooe Mar 12 '18 at 16:38
  • The limit on query rows is not the governor you're worried about blowing up. It's the limit on queries. This one is really easy to pull outside the loop using Map<Id, Account>([/*soql*/]). You can cache a Set<Id> accountIds by iterating through trigger.new and pulling out each AccountId. – Adrian Larson Mar 12 '18 at 16:39
  • We'd need to see your unit test. My best guess is that you forgot to query the account back from the database. – sfdcfox Mar 12 '18 at 16:40
  • @sfdcfox I have updated to show my unit test – Briscoooe Mar 12 '18 at 16:45

You need to re-query the database. Also note that the syntax for assertions is to put the expected value first, then the actual value. You should also strongly consider adding informative assertion messages. They add a lot of value to your test suite.


acc = [SELECT Pipeline_Start__c FROM Account WHERE Id = :acc.Id];
system.assertEquals(Date.today(), acc.Pipeline_Start__c, 'Add some informative message');

Also note you have two separate governors which are going to explode if you operate on a collection. You query and update within a loop. You do not even need to query for records to update them if you already know their Id. You can change your code to the following and it will be much more bulk safe:

Date today = Date.today();
Map<Id, Account> accounts = new Map<Id, Account>();
for (Opportunity record : trigger.new)
    if (record.AccountId != null)
        accounts.put(record.AccountId, new Account(
            Id=record.AccountId, Pipeline_Start__c=today
update accounts.values();

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.