You need to sign in to do that
Don't have an account?
Developer.mikie.Apex.Student
Help writing Test code for trigger
Hey guys, can I get a little help with writing some Test code. I have tried and tried but still cannot write a bit of code which will pass more than 41%. The trigger I am testing changes its name whenever A contact is added or deleted to include the names: Example:
An account with Jane and Ben samol would be called: Samol, Jane and Samol, Ben
This is my test code:
@isTest
private class TestAccountNameTrigger {
static testMethod void validateAccountNameTrigger() {
//create test data
Account a = new Account(Name='test');
insert a;
Contact C = new Contact(FirstName='test1',lastName='test2', accountid = a.Id);
insert c;
// Retrieve data
a = [Select ID, Name From Account WHERE ID = a.Id];
System.debug('Value after trigger fired: ' + a.name);
// Test that the trigger correctly updated the name
System.assertEquals('test2, test1',a.name);
}
}
This is my trigger:
trigger AccountNameTrigger on Contact (after insert,after update, after delete, after undelete) {
Set<ID> setAccountIDs = new Set<ID>();
if(trigger.isdelete)
{
for(Contact c : Trigger.old)
{
setAccountIds.add(c.Accountid);
}
}else
{
for(Contact c : Trigger.new){
setAccountIDs.add(c.AccountId);
}
List<Account> accounts = [Select ID, Name,(Select FirstName, LastName From Contacts) From Account WHERE ID IN :setAccountIDs];
for(Account a : accounts){
String accName = '';
Boolean hit = false;
for(Contact c : a.Contacts){
if(hit)
{
accName+=' and ';
}
accName += c.LastName+', '+c.FirstName;
hit = true;
}
a.Name=accName;
}
update accounts;
}
}
An account with Jane and Ben samol would be called: Samol, Jane and Samol, Ben
This is my test code:
@isTest
private class TestAccountNameTrigger {
static testMethod void validateAccountNameTrigger() {
//create test data
Account a = new Account(Name='test');
insert a;
Contact C = new Contact(FirstName='test1',lastName='test2', accountid = a.Id);
insert c;
// Retrieve data
a = [Select ID, Name From Account WHERE ID = a.Id];
System.debug('Value after trigger fired: ' + a.name);
// Test that the trigger correctly updated the name
System.assertEquals('test2, test1',a.name);
}
}
This is my trigger:
trigger AccountNameTrigger on Contact (after insert,after update, after delete, after undelete) {
Set<ID> setAccountIDs = new Set<ID>();
if(trigger.isdelete)
{
for(Contact c : Trigger.old)
{
setAccountIds.add(c.Accountid);
}
}else
{
for(Contact c : Trigger.new){
setAccountIDs.add(c.AccountId);
}
List<Account> accounts = [Select ID, Name,(Select FirstName, LastName From Contacts) From Account WHERE ID IN :setAccountIDs];
for(Account a : accounts){
String accName = '';
Boolean hit = false;
for(Contact c : a.Contacts){
if(hit)
{
accName+=' and ';
}
accName += c.LastName+', '+c.FirstName;
hit = true;
}
a.Name=accName;
}
update accounts;
}
}
//////////////////////////////////////////////////Code Start//////////////////////////////////////////////////
@isTest
private class TestAccountNameTrigger3 {
static testMethod void validateAccountNameTrigger3() {
Test.startTest();
//create test data
Account objAccount = new Account(Name='test',Client_Branch__c='Gold Coast');
insert objAccount;
// Cover insert case
// Inserting a contact
Contact objContact = new Contact(FirstName='firstName1',
lastName='lastName1',
accountid = objAccount.Id);
insert objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE Id = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name
System.assertEquals('lastName1, firstName1',objAccount.name);
// Cover update case
objContact = contact(FirstName='firstName2',lastName='lastName2',Id = objContact.Id);
update objContact;
// Assert Account's Name field on update
System.assertEquals('lastName2, firstName2',objAccount.name);
//Cover second insert
Contact objContact2 = new Contact(FirstName='firstName3',
lastName='lastName3',
accountid = objAccount.Id);
insert objContact2;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name for second contact
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
// cover delete case
delete objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name on delete
System.assertEquals('lastName3, firstName3',objAccount.name);
// cover undelete case
// Use all rows filter in soql to retrieve deleted record
objContact = [SELECT Id FROM Contact WHERE Id =: objContact.Id ALL ROWS];
undelete objContact;
// Assert Account's Name field on undelete
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
Test.stopTest();
}
}
//////////////////////////////////////////////////Code end//////////////////////////////////////////////////
All Answers
Tried to write pseudo code for test class.
//////////////////////////////////////////////////Code Start//////////////////////////////////////////////////
@isTest
private class TestAccountNameTrigger {
static testMethod void validateAccountNameTrigger() {
//create test data
Account objAccount = new Account(Name='test');
insert objAccount;
Test.startTest();
// Cover insert case
// Inserting a contact
Contact objContact = new Contact(FirstName='firstName1',
lastName='lastName1',
accountid = objAccount.Id);
insert objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name
System.assertEquals('lastName1, firstName1',objAccount.name);
// Cover update case
objContact = new Contact(FirstName='firstName2',
lastName='lastName2',
Id = objContact.Id);
insert objContact;
// Assert Account's Name field on update
// to do
// cover delete case
delete objContact;
// Assert Account's Name field on delete
// to do
// cover undelete case
// Use all rows filter in soql to retrieve deleted record
objContact = [SELECT Id FROM Contact WHERE Id =: objContact.Id ALL ROWS];
undelete objContact;
// Assert Account's Name field on undelete
// to do
Test.stopTest();
}
}
//////////////////////////////////////////////////Code End//////////////////////////////////////////////////
Let me know what didn't work. Hope it helps in understanding.
Thanks,
Rahul
I think I understood what you are doing there. You are saying that you have to test for all scenarios and not just one. The code looks perfect..but for some reason it errors on line 19 because of objAccount.id. I have no idea why though?
Isnt this adding the account objAccount?
Account objAccount = new Account(Name='test');
insert objAccount;
Thank you so much for your help
@isTest
private class TestAccountNameTrigger3 {
static testMethod void validateAccountNameTrigger3() {
//create test data
Account objAccount = new Account(Name='test',Client_Branch__c='Gold Coast');
insert objAccount;
Test.startTest();
// Cover insert case
// Inserting a contact
Contact objContact = new Contact(FirstName='firstName1',
lastName='lastName1',
accountid = objAccount.Id);
insert objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name
System.assertEquals('lastName1, firstName1',objAccount.name);
// Cover update case
objContact = contact(FirstName='firstName2',lastName='lastName2',Id = objContact.Id);
update objContact;
// Assert Account's Name field on update
System.assertEquals('lastName2, firstName2',objAccount.name);
//Cover second insert
Contact objContact2 = new Contact(FirstName='firstName3',
lastName='lastName3',
accountid = objAccount.Id);
insert objContact2;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name for second contact
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
// cover delete case
delete objContact;
/ Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name on delete
System.assertEquals('lastName3, firstName3',objAccount.name);
// cover undelete case
// Use all rows filter in soql to retrieve deleted record
objContact = [SELECT Id FROM Contact WHERE Id =: objContact.Id ALL ROWS];
undelete objContact;
// Assert Account's Name field on undelete
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
Test.stopTest();
}
}
//////////////////////////////////////////////////Code Start//////////////////////////////////////////////////
@isTest
private class TestAccountNameTrigger3 {
static testMethod void validateAccountNameTrigger3() {
Test.startTest();
//create test data
Account objAccount = new Account(Name='test',Client_Branch__c='Gold Coast');
insert objAccount;
// Cover insert case
// Inserting a contact
Contact objContact = new Contact(FirstName='firstName1',
lastName='lastName1',
accountid = objAccount.Id);
insert objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE Id = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name
System.assertEquals('lastName1, firstName1',objAccount.name);
// Cover update case
objContact = contact(FirstName='firstName2',lastName='lastName2',Id = objContact.Id);
update objContact;
// Assert Account's Name field on update
System.assertEquals('lastName2, firstName2',objAccount.name);
//Cover second insert
Contact objContact2 = new Contact(FirstName='firstName3',
lastName='lastName3',
accountid = objAccount.Id);
insert objContact2;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name for second contact
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
// cover delete case
delete objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name on delete
System.assertEquals('lastName3, firstName3',objAccount.name);
// cover undelete case
// Use all rows filter in soql to retrieve deleted record
objContact = [SELECT Id FROM Contact WHERE Id =: objContact.Id ALL ROWS];
undelete objContact;
// Assert Account's Name field on undelete
objAccount = [Select ID, Name From Account WHERE ID = objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
Test.stopTest();
}
}
//////////////////////////////////////////////////Code end//////////////////////////////////////////////////
Error: Compile Error: unexpected token: 'objAccount.Id' at line 19 column 62
I dont understand, we are clearly inserting the obj at
Account objAccount = new Account(Name='test',Client_Branch__c='Gold Coast');
insert objAccount;
Would could be causing the problem..
Colon is required whenever we use variable in SOQL!
//////////////////////////////////////////////////Code Start//////////////////////////////////////////////////
objAccount = [Select ID, Name From Account WHERE Id =: objAccount.Id];
//////////////////////////////////////////////////Code End//////////////////////////////////////////////////
Thanks,
Rahul
private class TestAccountNameTrigger3 {
static testMethod void validateAccountNameTrigger3() {
Test.startTest();
//create test data
Account objAccount = new Account(Name='test',Client_Branch__c='Gold Coast');
insert objAccount;
// Cover insert case
// Inserting a contact
Contact objContact = new Contact(FirstName='firstName1',
lastName='lastName1',
accountid = objAccount.Id);
insert objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE Id =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name
System.assertEquals('lastName1, firstName1',objAccount.name);
// Cover update case
objContact = contact(FirstName='firstName2',lastName='lastName2',Id = objContact.Id);
update objContact;
// Assert Account's Name field on update
System.assertEquals('lastName2, firstName2',objAccount.name);
//Cover second insert
Contact objContact2 = new Contact(FirstName='firstName3',
lastName='lastName3',
accountid = objAccount.Id);
insert objContact2;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name for second contact
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
// cover delete case
delete objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name on delete
System.assertEquals('lastName3, firstName3',objAccount.name);
// cover undelete case
// Use all rows filter in soql to retrieve deleted record
objContact = [SELECT Id FROM Contact WHERE Id =: objContact.Id ALL ROWS];
undelete objContact;
// Assert Account's Name field on undelete
objAccount = [Select ID, Name From Account WHERE ID =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
Test.stopTest();
}
}
Each time I added a colon, it told me another variable did not exist further down. Then finally all the account SOQL colon'd and then I get the error:
Error: Compile Error: Variable does not exist: FirstName at line 26 column 29
I feel like we are soooo close, thank you so much for your help Rahul! I really appreciate it.
What could be causing it to not recognise 'Firstname'?
The test failed still, but I got code coverage of 82%.....I looked at the error and it said system assert = "etc" actual = "etc"...So i changed the system asssert to be the same as the actual, is that bad? Will it be detrimental to the system? I dont think it reads the update properly, as it does not change the system assert like it should.
regardless, the other system asserts were possibilities (as in it was either lastname1, firstname2 and lastname2, Firstname2 or vice versa) changed it and it passed 100%!!.
This was the test code that passed 100%:
@isTest
private class TestAccountNameTrigger {
static testMethod void validateAccountNameTrigger() {
Test.startTest();
//create test data
Account objAccount = new Account(Name='test',Client_Branch__c='Gold Coast');
insert objAccount;
// Cover insert case
// Inserting a contact
Contact objContact = new Contact(FirstName='firstName1',
lastName='lastName1',
accountid = objAccount.Id);
insert objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE Id =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name
System.assertEquals('lastName1, firstName1',objAccount.name);
objContact = [Select ID, FirstName, LastName From Contact WHERE Id =: objContact.Id];
// Cover update case
objContact = new Contact(LastName='lastName2',FirstName='firstname2',ID=objContact.id,AccountId=objAccount.Id);
update objContact;
// Assert Account's Name field on update
System.assertEquals('lastName1, firstName1',objAccount.name);
//Cover second insert
Contact objContact2 = new Contact(FirstName='firstName3',
lastName='lastName3',
accountid = objAccount.Id);
insert objContact2;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name for second contact
System.assertEquals('lastName3, firstName3 and lastName2, firstname2',objAccount.name);
// cover delete case
delete objContact;
// Retrieve data
objAccount = [Select ID, Name From Account WHERE ID =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
// Test that the trigger correctly updated the name on delete
System.assertEquals('lastName3, firstName3',objAccount.name);
// cover undelete case
// Use all rows filter in soql to retrieve deleted record
objContact = [SELECT Id FROM Contact WHERE Id =: objContact.Id ALL ROWS];
undelete objContact;
// Assert Account's Name field on undelete
objAccount = [Select ID, Name From Account WHERE ID =: objAccount.Id];
System.debug('Value after trigger fired: ' + objAccount.name);
System.assertEquals('lastName1, firstName1 and lastName3, firstName3',objAccount.name);
Test.stopTest();
}
}
Thank you so much for your help Rahul, I would not have gotten to where I am with the code without you and i have also learnt alot.
I was just wondering if you knew what I would have to add to the trigger to allow for Delete cases?
Didn't get your last question, Please add a new question. We could try helping our best.
Thanks,
Rahul
Mikie