function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Base LineBase Line 

Problem with the Apex testing

Hi. I am trying to implement an interface that will perform the following filter on input records.

- Do not include any record that has the field “Deleted__c” as true. (I have already created this custom field in the Account object)
- Do not include any record that is newer than 24 hours.
- Do not include any record that has an address outside of Japan.

Unfortunately, when I try the unit tests I created,  there are some System.AssertException errors. Having searched all over the internet for possible solutions, I am at a loss at what I am doing wrong. Please have a look at my code and guide me on what I should change. Any help would be greatly appreciated. Many thanks in advance.

INTERFACE
public interface IFilter {
List<Account> filter(List<Account> records);
}

IMPLEMENTATION
public class AccountFilterJapanOnly implements IFilter{

    public List<Account> filter(List<Account> records)
    {
        DateTime twentyFourHoursAgo = DateTime.now().addHours(-24);
        List<String> jpCountry = new List<String>{'Japan', 'JP'};
        
        List<Account> returnedAccountsList = new List<Account>();
        
        for( Account matchingAccount : [SELECT Name, AccountNumber, BillingAddress, Deleted__c, CreatedDate
                                        FROM Account
                                        WHERE Deleted__c != TRUE AND 
                                             CreatedDate < :twentyFourHoursAgo AND
                                            BillingCountry IN :jpCountry])
        {
            System.debug(matchingAccount);
            returnedAccountsList.add(matchingAccount);
        }
        
        return returnedAccountsList;
    }    
}

UNIT TESTS
@isTest
public class AccountFilterJapanOnlyTest {

    //NOT WORKING AS EXPECTED
    @isTest static void testDeletedField()
    {
        Account testAccDelTrue = new Account(Name='DeletedFieldTrue', Deleted__c=TRUE);
        Account testAccDelFalse = new Account(Name='DeletedFieldFalse', Deleted__c=FALSE);
        Account[] accts = new Account[]{testAccDelTrue, testAccDelFalse};
        //Insert accts;
        
        Test.startTest();
        AccountFilterJapanOnly jpRecords = new AccountFilterJapanOnly();
        List<Account> lst = jpRecords.filter(accts);
        Test.stopTest();
        
        System.assertEquals(1, lst.size());
        System.assertEquals(testAccDelFalse, lst[0]);        
    }
    
    //GIVING CORRECT RESULTS BUT STILL UNSURE IF THIS IS ACCURATE
    @isTest static void testCreatedDate()
    {        
        Account testCreatedDate = new Account(Name='Created Within 24 hours');
        Account[] accts = new Account[]{testCreatedDate};
        Insert accts;
        
        Test.startTest();
        AccountFilterJapanOnly jpRecords = new AccountFilterJapanOnly();
        List<Account> lst = jpRecords.filter(accts);
        Test.stopTest();
        
        System.assertEquals(0, lst.size());        
    }
    
    //NOT WORKING AS EXPECTED
    @isTest static void testLocation()
    {       
        Account testOutsideJapan = new Account(Name='Address Outside Japan', BillingCountry='USA');
        Account testWithinJapan1 = new Account(Name='Address1 Within Japan', BillingCountry='Japan');
        Account testWithinJapan2 = new Account(Name='Address2 Within Japan', BillingCountry='JP');
        Account[] accts = new Account[]{testOutsideJapan,testWithinJapan1,testWithinJapan2};
        Insert accts;
        
        Test.startTest();
        AccountFilterJapanOnly jpRecords = new AccountFilterJapanOnly();
        List<Account> lst = jpRecords.filter(accts);
        Test.stopTest();
        
        System.assertEquals(2, lst.size());
        System.assertEquals(true, lst.contains(testWithinJapan1));
        System.assertEquals(true, lst.contains(testWithinJapan2));
    }
}



 
Best Answer chosen by Base Line
Alain CabonAlain Cabon
Always fill all the fields of the filter in the SOQL request.

  WHERE Deleted__c != TRUE AND 
                CreatedDate < :twentyFourHoursAgo AND
                BillingCountry IN :jpCountry])
 
@isTest static void testCreatedDate()
    {        
        Account testCreatedDate1 = new Account(Name='Created Within 24 hours',BillingCountry='Japan', Deleted__c=FALSE);
        Account testCreatedDate2 = new Account(Name='Not Created Within 24 hours',BillingCountry='Japan', Deleted__c=FALSE);
        List<Account> accts = new List<Account>{testCreatedDate1, testCreatedDate2};
        Insert accts;
        
        DateTime beforeYesterday = DateTime.now().addDays(-2);
        Test.setCreatedDate(testCreatedDate2.Id, beforeYesterday);        
        
        Test.startTest();
        AccountFilterJapanOnly jpRecords = new AccountFilterJapanOnly();
        List<Account> lst = jpRecords.filter(accts);
        Test.stopTest();
        
        System.assertEquals(1, lst.size()); 
        
        // the created account has the same Id/Name of testCreatedDate2
        System.assertEquals(lst[0].Id, testCreatedDate2.Id);
        System.assertEquals(lst[0].Name, testCreatedDate2.Name);
        
    }

 

All Answers

Alain CabonAlain Cabon
@Base Line

You filter the records before yesterday.

We can use yesterday directly in SOQL:  CreatedDate < :twentyFourHoursAgo   or just: CreatedDate < YESTERDAY

You create the record now by a test and by default the created datetime is the current time.

If you want to create records before yesterday, you need to force the created datetime;

Test.setCreatedDate(recordId, createdDatetime) : Sets CreatedDate for a test-context sObject.

Account account = new Account(Name = 'Test');
insert account;
Datetime before_yesterday = Datetime.now().addDays(-2);
// change the created date of the created account
Test.setCreatedDate(account.Id, before_yesterday);

 
Base LineBase Line
Hi Alain. Thank you for your response. I wasn't aware it was possible to change the CreateDate parameter of the test.

I changed up the code for the testCreatedDate to as follows:
@isTest static void testCreatedDate()
    {        
        Account testCreatedDate1 = new Account(Name='Created Within 24 hours');
        Account testCreatedDate2 = new Account(Name='Not Created Within 24 hours');
        List<Account> accts = new List<Account>{testCreatedDate1, testCreatedDate2};
        Insert accts;
        
        DateTime beforeYesterday = DateTime.now().addDays(-2);
        Test.setCreatedDate(testCreatedDate2.Id, beforeYesterday);        
        
        Test.startTest();
        AccountFilterJapanOnly jpRecords = new AccountFilterJapanOnly();
        List<Account> lst = jpRecords.filter(accts);
        Test.stopTest();
        
        System.assertEquals(1, lst.size()); 
        System.assertEquals(true, lst.contains(testCreatedDate2));
    }


Unfortunately, none of the 3 tests are running well. These are the errors I am getting at the points of the assertEquals test for list size. Could you please tell me what could be the problem? Much appreciated.

System.AssertException: Assertion Failed: Expected: 1, Actual: 0
System.AssertException: Assertion Failed: Expected: 1, Actual: 0
System.AssertException: Assertion Failed: Expected: 2, Actual: 0
 
Alain CabonAlain Cabon
Always fill all the fields of the filter in the SOQL request.

  WHERE Deleted__c != TRUE AND 
                CreatedDate < :twentyFourHoursAgo AND
                BillingCountry IN :jpCountry])
 
@isTest static void testCreatedDate()
    {        
        Account testCreatedDate1 = new Account(Name='Created Within 24 hours',BillingCountry='Japan', Deleted__c=FALSE);
        Account testCreatedDate2 = new Account(Name='Not Created Within 24 hours',BillingCountry='Japan', Deleted__c=FALSE);
        List<Account> accts = new List<Account>{testCreatedDate1, testCreatedDate2};
        Insert accts;
        
        DateTime beforeYesterday = DateTime.now().addDays(-2);
        Test.setCreatedDate(testCreatedDate2.Id, beforeYesterday);        
        
        Test.startTest();
        AccountFilterJapanOnly jpRecords = new AccountFilterJapanOnly();
        List<Account> lst = jpRecords.filter(accts);
        Test.stopTest();
        
        System.assertEquals(1, lst.size()); 
        
        // the created account has the same Id/Name of testCreatedDate2
        System.assertEquals(lst[0].Id, testCreatedDate2.Id);
        System.assertEquals(lst[0].Name, testCreatedDate2.Name);
        
    }

 
This was selected as the best answer
Base LineBase Line
Hi Alain,

Wow - can't thank you enough! Your advice was spot on and thanks to you the code coverage is at 100% and every test was successful. I owe you one!