You need to sign in to do that
Don't have an account?
Ryan Reese
Test Class Code?
Newb apex - how do I build test class for the following trigger and someone told me not to hardcode the chatter group id how should I reference it in the code?
trigger OppWonChatter on Opportunity (after insert, after update) {
String status;
String OppAccName;
String OppOwnerName;
String OppName;
FeedItem post = new FeedItem();
for(Opportunity o : Trigger.new) {
if(o.OwnerId == '00560000001MxXV') { //It will not post record for for this user to group. changed last letter to cap v so i can test
return;
}
else {
if(Trigger.isInsert ) {
if( o.IsWon == true ) { //This will be executed on new record insertion
for (Opportunity oppty : [SELECT Account.Name, Owner.Name, Name FROM Opportunity WHERE Id =:o.Id] ) {
OppAccName = oppty.Account.Name;
OppName = oppty.Name;
OppOwnerName = oppty.Owner.Name;
}
status = OppOwnerName + ' just won ' + OppName + '!';
post.ParentId = '0F9m00000008ZTM';
post.Title = o.Name;
post.Body = status;
insert post;
}
}
else {
if ( Trigger.isUpdate ) {
if( o.IsWon == true ) { //This will be executed on update to existing record
for (Opportunity oppty : [SELECT Account.Name, Owner.Name, Name FROM Opportunity WHERE Id =:o.Id] ) {
OppName = oppty.Name;
OppAccName = oppty.Account.Name;
OppOwnerName = oppty.Owner.Name;
}
status = OppOwnerName + ' just won ' + OppName + '!';
post.ParentId = '0F9m00000008ZTM';
post.Title = o.Name;
post.Body = status;
trigger OppWonChatter on Opportunity (after insert, after update) {
String status;
String OppAccName;
String OppOwnerName;
String OppName;
FeedItem post = new FeedItem();
for(Opportunity o : Trigger.new) {
if(o.OwnerId == '00560000001MxXV') { //It will not post record for for this user to group. changed last letter to cap v so i can test
return;
}
else {
if(Trigger.isInsert ) {
if( o.IsWon == true ) { //This will be executed on new record insertion
for (Opportunity oppty : [SELECT Account.Name, Owner.Name, Name FROM Opportunity WHERE Id =:o.Id] ) {
OppAccName = oppty.Account.Name;
OppName = oppty.Name;
OppOwnerName = oppty.Owner.Name;
}
status = OppOwnerName + ' just won ' + OppName + '!';
post.ParentId = '0F9m00000008ZTM';
post.Title = o.Name;
post.Body = status;
insert post;
}
}
else {
if ( Trigger.isUpdate ) {
if( o.IsWon == true ) { //This will be executed on update to existing record
for (Opportunity oppty : [SELECT Account.Name, Owner.Name, Name FROM Opportunity WHERE Id =:o.Id] ) {
OppName = oppty.Name;
OppAccName = oppty.Account.Name;
OppOwnerName = oppty.Owner.Name;
}
status = OppOwnerName + ' just won ' + OppName + '!';
post.ParentId = '0F9m00000008ZTM';
post.Title = o.Name;
post.Body = status;
You can use custom settings to store the ids, and refer them in your code, which gives you the flexibility to change it whenever needed.
For eg., create a custom setting named SFDC Ids which has api name SFDC_IDS__C and a field called value with api name value__c for that setting.
Create a record in custom setting say Name="your chatter group name" and value="id of the chatter group".
you can get the value of the id in the code like this:
SFDC_IDS__C.getInstance('your chatter group name').value__c // This will even save a query for you.
To access/create custom settings go to setup>Develop>custom settings
I can guide you:
First you need to prepare test data to test it!
@isTest
public class OppWonChatter_isTest{
public static testMethod void test_ChatterPostOnOpp(){
//Create custom setting data
SFDC_IDS__C testDataForExemptUser=new SFDC_IDS__C(Name='Name of Exempt User',Value__c=Userinfo.getUserId());
insert testDataForExemptUser;
SFDC_IDS__C testDataForIdToPostChatter=new SFDC_IDS__C(Name='Name of Exempt User',Value__c=Userinfo.getUserId());
insert testDataForIdToPostChatter;
//Create test data for account
Account testAccount=new Account(Name='sample Name');
insert testAccount;
//Create testUser
Profile systemAdminProfile = [SELECT Id FROM Profile WHERE Name='System Administrator'];
User testUser = new User(Alias = 'standt', Email='standarduser@testorg.com', EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', LocaleSidKey='en_US', ProfileId = systemAdminProfile.Id, TimeZoneSidKey='America/Los_Angeles', UserName='testUser565558454@OppWonChatter_isTest.com');
// create test data for Opportunity
opportunity testOpportunity=new Opportunity(Name='Sample name',AccountId=testAccount.id,IsWon=True);
//Assuming the owner will be you, the post code should cover, now change
insert testOpportunity;
testOpportunity.OwnerId=testUser.id;
update testOpportunity;
//Now the update on oppotunity will be fired by covering the last part of code
system.runAs(testUser){
opportunity testOpportunityByTestUser=new Opportunity(Name='Sample name',AccountId=testAccount.id,IsWon=True);
insert testOpportunityByTestUser;
update testOpportunityByTestUser;
}
}
}
And the tigger needs to be modified(suggestions):
* It is not bulkified - written a DML statement in a for loop. Try to capture everything into a list and do a DML on list after the loop closes
* you are doing a query inside a for loop, instead you can collect the opportunity ids all at once and query in bulk which saves your query.
in the above case you can get all the ids all at once using trigger.newMap.keyset(); then query all the opportunities with those ids and parse through them.
*Lot of repetitive lines of code, in case of insert or update there are few statements which can be clubed together so that you could save some lines of code as well as it looks pretty.
Note:I wrote the test class assuming you already used custom settings, if not you doesnt need to insert any custom setting in test class. instead you would need to query for the user with those hard coded ids which needs (SeeAllData=True) annotation.** Not suggestable, so use custom settings :)
Hope this will help you writing test class
Thanks,
balaji
Component Error - opportunityProductEntryTests.theTests(), Details: System.DmlException: Delete failed. First exception on row 0 with id 00k60000009NoHFAA0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Please update the reason we lost this deal.: [] Class.opportunityProductEntryExtension.onSave: line 173, column 1 Class.opportunityProductEntryTests.theTests: line 47, column 1
Apex Test Failure - opportunityProductEntryTests theTests System.DmlException: Delete failed. First exception on row 0 with id 00k60000009NoHFAA0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Please update the reason we lost this deal.: []
Stack Trace: Class.opportunityProductEntryExtension.onSave: line 173, column 1 Class.opportunityProductEntryTests.theTests: line 47, column 1
@istest (SeeAllData=True)
private class OppWonTestClass {
static testMethod Void validateMethod(){
Opportunity oppn = new Opportunity();
oppn.Name = 'Test code - Apex trigger oppn';
oppn.StageName= 'Closed Won'; // Put your Stage Name
oppn.CloseDate = System.Today();
oppn.Won_Reason__c = 'Pricing';
oppn.Lost_Reason__c = 'Pricing';
insert oppn; } }
Sorry if i confused you, i tried to explain you the best practices to fix the code you posted as it is vulnarable to hit governor limit due to lack of bulkification concept usage.
opportunityProductEntryTests is a test class which is failing as it hit a validation rule in your org which is asking to enter the Reason why the deal is lost! Its your orgs customized features so i assume any outsider help will be limited as we will have no idea what type of customizations your org went thru.
Note: Im not sure you if you are running multiple test classes because if there is any error with "OppWonTestClass " it says the error is with that particular class.
Thanks,
balaji
@istest private class opportunityProductEntryTests { static testMethod void theTests(){ // You really should create test data, but I'm going to query instead // It's my best shot of avoiding a test failure in most orgs // Once you've installed this package though, you might want to write your own tests // or at least customize these ones to make them more applicable to your org OpportunityLineItem oli = [select Id, PricebookEntryId, PricebookEntry.Pricebook2Id, PricebookEntry.Name, PriceBookEntry.Product2Id, OpportunityId, Opportunity.AccountId from OpportunityLineItem limit 1]; //////////////////////////////////////// // test opportunityProductEntry //////////////////////////////////////// // load the page PageReference pageRef = Page.opportunityProductEntry; pageRef.getParameters().put('Id',oli.OpportunityId); Test.setCurrentPageReference(pageRef); // load the extension opportunityProductEntryExtension oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(oli.Opportunity)); // test 'getChosenCurrency' method if(UserInfo.isMultiCurrencyOrganization()) System.assert(oPEE.getChosenCurrency()!=''); else System.assertEquals(oPEE.getChosenCurrency(),''); // we know that there is at least one line item, so we confirm Integer startCount = oPEE.ShoppingCart.size(); system.assert(startCount>0); //test search functionality without finding anything oPEE.searchString = 'michaelforce is a hip cat'; oPEE.updateAvailableList(); system.assert(oPEE.AvailableProducts.size()==0); //test remove from shopping cart oPEE.toUnselect = oli.PricebookEntryId; oPEE.removeFromShoppingCart(); system.assert(oPEE.shoppingCart.size()==startCount-1); //test save and reload extension oPEE.onSave(); oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(oli.Opportunity)); system.assert(oPEE.shoppingCart.size()==startCount-1); // test search again, this time we will find something oPEE.searchString = oli.PricebookEntry.Name; oPEE.updateAvailableList(); system.assert(oPEE.AvailableProducts.size()>0); // test add to Shopping Cart function oPEE.toSelect = oPEE.AvailableProducts[0].Id; oPEE.addToShoppingCart(); system.assert(oPEE.shoppingCart.size()==startCount); // test save method - WITHOUT quanitities and amounts entered and confirm that error message is displayed oPEE.onSave(); system.assert(ApexPages.getMessages().size()>0); // add required info and try save again for(OpportunityLineItem o : oPEE.ShoppingCart){ o.quantity = 5; o.unitprice = 300; } oPEE.onSave(); // query line items to confirm that the save worked opportunityLineItem[] oli2 = [select Id from opportunityLineItem where OpportunityId = :oli.OpportunityId]; system.assert(oli2.size()==startCount); // test on new Opp (no pricebook selected) to make sure redirect is happening Opportunity newOpp = new Opportunity(Name='New Opp',stageName='Pipeline',Amount=10,closeDate=System.Today()+30,AccountId=oli.Opportunity.AccountId); insert(newOpp); oPEE = new opportunityProductEntryExtension(new ApexPages.StandardController(newOpp)); System.assert(oPEE.priceBookCheck()!=null); // final quick check of cancel button System.assert(oPEE.onCancel()!=null); //////////////////////////////////////// // test redirect page //////////////////////////////////////// // load the page pageRef = Page.opportunityProductRedirect; pageRef.getParameters().put('Id',oli2[0].Id); Test.setCurrentPageReference(pageRef); // load the extension and confirm that redirect function returns something opportunityProductRedirectExtension oPRE = new opportunityProductRedirectExtension(new ApexPages.StandardController(oli2[0])); System.assert(oPRE.redirect()!=null); } }
@Ryan Reese:
It might be more dangerous as every time you need to turn it off while deployment (users will be still working). Instead cant the validation rule bypass/exempt system admin profile users, so that there wont be any issues with testclass installed from unmanaged packages??