1

I am having trouble creating a test class for this particular class. If anyone could provide some code that would implement this I would be very grateful. Many thanks

CLASS

global class ModifiedDate implements Database.Batchable<sObject> {
List<Contact> ctt = new List<Contact>();
List<Account> acct = new List<Account>();
String query= 'SELECT Id,Name,Phone,LastModifiedDate,LastContact__c,(SELECT Id,AccountId,Name,Phone FROM Contacts) FROM Account WHERE Accountcheck__c = TRUE    AND Donotruncontact_Management__c = FALSE'; 
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Account> scope) {
    System.debug('!@#'+ scope);
    for(Account acc: scope){
        acc.LastContact__c = DateTime.now();
        System.debug('!@#'+acc.LastContact__c);
        for(Contact ctct: acc.Contacts){
            ctct.Phone = acc.Phone;
            ctt.add(ctct);
            System.debug('!@#'+ctct.Phone);
        }
        acct.add(acc);
    }
    update acct;
    System.debug('!@#'+ acct);
    update ctt;
    System.debug('!@#'+ ctt);

}

global void finish(Database.BatchableContext BC) {
    //code to do when the batch job finished
    System.debug('>>>>> Finish Execution: ' + System.now().format());
}
}

TEST CLASS

@isTest
public with sharing class ModifiedDate_Test {
public ModifiedDate_Test() {
    // Implement test code
System.Test.startTest();
String query = 'SELECT Id,Name,Phone,LastModifiedDate,LastContact__c,(SELECT Id,AccountId,Name,Phone FROM Contacts) FROM Account WHERE Accountcheck__c = TRUE AND Donotruncontact_Management__c = FALSE';
ModifiedDate sf = new ModifiedDate_Test(query);
Database.executeBatch(sf);
System.Test.stopTest();
}
}

2 Answers 2

1
global class ModifiedDate implements Database.Batchable<sObject> {
    // Inline the query; we would only use a string if we needed to modify
    // it explicitly for the test.
    global Database.QueryLocator start(Database.BatchableContext context) {
        // Only query fields you need; we will get fresh data later
        return Database.getQueryLocator([SELECT Id FROM Account WHERE Accountcheck__c = TRUE AND Donotruncontact_Management__c = FALSE]);
    }

    global void execute(Database.BatchableContext BC, List<Account> scope) {
        // variables should always have minimum scope. So we put them here.
        Map<Id, Account> accounts = new Map<Id, Account>([SELECT Phone FROM Account WHERE ID IN :scope FOR UPDATE]);
        // Lock parents, then children
        Contact[] contacts = [SELECT AccountId FROM Contact WHERE AccountId IN :scope FOR UPDATE]);
        // Update the field
        for(Account record: accounts.values()) {
             record.LastContact__c = DateTime.now();
        }
        // Copy phone value
        for(Contact record: contacts) {
             record.Phone = accounts.get(record.AccountId).Phone;
        }
        // Update everything
        update accounts.values();
        update contacts;
    }

    global void finish(Database.BatchableContext BC) {
    }
}

Next, we can write your test method:

@isTest class ModifiedDate_Test {
    @isTest static void test() {
        // Use isolation mode-- we need to make test data
        Account a = new Account(Name='Test',Phone='12345',AccountCheck__c=true,Donotruncontact_Management__c=false);
        insert a;
        Contact c = new Contact(LastName='Test',AccountId=a.Id,Phone='1234');
        insert c;
        System.Test.startTest();
ModifiedDate sf = new ModifiedDate_Test();
        Database.executeBatch(sf,1);
        System.Test.stopTest();
        // We need to query the new values from the database
        c = [select phone from contact];
        a = [select lastcontact__c from account];
        // Always check the expected results
        system.assertEquals(a.Phone, c.Phone);
        system.assertnotequals(null, a.lastcontact__c);
    }
}
1

You should remove your constructor:

public ModifiedDate_Test() {

And instead make a testmethod like this:

static testMethod void testModifiedDate(){

I'm not sure if you intended to make a constructor for this class, but you don't need one. Also, all test methods need to have a signature of

static testmethod void

or

@isTest
static void
2
  • -1 mostly because you said that test classes can't have constructors. This is untrue. Nothing prevents you from having any number of constructors in a test class. In fact, I have several classes that do have constructors, because they provide additional utility beyond just running tests. Of course, it's useless for running a test, but that's a different situation altogether.
    – sfdcfox
    Commented Mar 20, 2015 at 2:39
  • I've changed it - I meant to say that he didn't need one. I also have a couple of test classes with empty constructors, mainly because I haven't removed them - they do compile though. Please remove that downvote. Commented Mar 20, 2015 at 2:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .