I have an Apex controller which unsubscirbes users from email via an opt-out form. I have written a test class which tests the method (or atleast partially at the moment). I would like to know how I could test returned page messages and also negative testing (where the user is already unsubscribed, could I simply creata a new instance of the PageReference and controller?
Controller:
public class unsubscribe_user {
public String email {
get;
set;
}
public String token {
get;
set;
}
public unsubscribe_user() {}
public PageReference unsubscribeMe() {
try {
List<Contact> contactList = [
select Name,
Email,
HasOptedOutOfEmail
from Contact
where Email = :email and
Id = :token.substring(10) and
hasOptedOutOfEmail = false
limit 100
];
if (contactList.isEmpty()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Warning, 'You are not in our mailing list (you may have already been removed)'));
return null;
}
for (Contact contact: contactList) {
contact.hasOptedOutOfEmail = true;
}
update contactList;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Info, 'You have been successfully removed from our mailing list'));
} catch (System.QueryException e) {
System.debug(System.LoggingLevel.ERROR, 'Contact Query Issue: ' + e.getMessage());
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Fatal, 'FATAL Error: Please contact the administrator'));
}
return null;
}
}
Test Class:
@isTest
private class rsvp_user_test {
static testMethod void unsubscribeMe_test() {
Account acc = new Account();
acc.Name = 'TestAccount';
acc.Airport__c = 'LHR';
acc.Industry = 'Airline';
acc.LHR__c = true;
acc.AcctExtID__c = '123';
acc.Customer_Account_number__c = '112233';
acc.Compare_Customer_Accont_Number__c=112233;
insert acc;
Contact co = new Contact();
co.AccountId = acc.Id;
co.Email = 'johndoe_test@mail.com';
co.LastName = 'CONTACT';
co.Airport__c = 'LHR';
insert co;
PageReference pg = Page.Snsubscribe;
Test.setCurrentPage(pg);
unsubscribeMe controller = new unsubscribeMe();
// Act
controller.email = co.Email;
controller.unsubscribeMe();
// Assert
Contact insertedData = [SELECT Id, Email, HasOptedOutOfEmail FROM Contact WHERE Email = :co.Email];
System.assertEquals(insertedData.hasOptedOutOfEmail, true);
// test again
// System.assertEquals(insertedData.hasOptedOutOfEmail, co.Id);
}
}
Best Answer
You can use
ApexPages.getMessages()
within your test to get the page messages for the current context, then check that array to make sure that it contains the error message that you're expecting.This is the pattern I tend to use, even for single messages, as it can easily be adapted to check for multiple messages whilst not caring about what order they are added to the page.
Alternatively you can factor it out into a helper method:
Then use it as follows: