+ Start a Discussion

Test class

I've created a trigger to copy field value "Status" (which is picklist) from "Opportunity Products" to "Opportunities". Here is what i came up to:


trigger UpdateStatus on OpportunityLineItem (after insert, after update) {

    List<Opportunity> oppp = new List<Opportunity>();

    for (OpportunityLineItem oppLnItem : trigger.new)
        oppp.add (new Opportunity (Id=oppLnItem.Opportunity_Id__c, Status__c=oppLnItem.Status__c));

        update oppp;


Not sure if it works, but what I DO know is that i have absolutely no idea how to create a test class for this trigger :(((. Can you help? All the things I've googled about test classes seem so complicated, and i just cant find my way around.


Why don't you just create a standard workflow that copies the status from Opportunity Products to Opportunities?  They're a Master-Detail relationship, which means you're allowed to do cross-object field updates using standard workflows.


But if you want to make it with a trigger just for the experience (even though it's a lot more work)... first you need to understand what a test class is.  So all a test class is, is you typing out what records need to be created with what field values, if a salesforce user were to make those records manually in salesforce up to the point where your trigger would get executed.


So for example, you need to create an opportunity line item in order to run your trigger.  OpportunityLineItems are detail objects of Opportunities, meaning you'd need to make an opportunity record before you can make the OpportunityLineItem record.  And Opportunities are detail objects of Accounts, so you'd need to make an Account record before you can make the opportunity.  


It's important to keep in mind that all validations and required fields are verified during the test, so if you have a validation where you normally can't save a record if "X__c" field = "Y", then your test class will fail during the DML insert/update, because the validation you made won't allow that value, and same goes for frequired fields.  So make sure you populate all fields in your test records with the correct field values.


So your final test class would look something like:


@isTest  //this tells salesforce to run this class automatically whenever a trigger is saved to production.
public class testUpdateStatus{
   public static testmethod void test_1() {

      Account a = new Account();
      a.Name = 'AcmeCo';
      insert a;

      Opportunity o = new Opportunity();
      o.AccountID = a.Id;
      o.Name = 'Test Opportunity';
      o.StageName = '//the name of the stage that your opp would be in when this trigger is run';
      o.CloseDate = system.today();
      insert o;

      OpportunityLineItem oli = new OpportunityLineItem();
      oli.OpportunityId = o.Id;
      oli.UnitPrice = 100.00;
      oli.Quantity = 1;
      oli.Status__c = '//one of the status's you made';
      insert oli;



That's it.  They're not extremely difficult.


By the way, since all @isTest classes get run every time you save a trigger in production, often times another test class you wrote prior will actually cover the conditions needed to run your trigger.  So what I often do is I just write one BIG test class that I continually add to as I write additional triggers, where I'll just update the test class to create a new record or update a certain field value to meet the conditions needed to run all the code on the latest trigger I made.  It also makes it easier to see why a test class fails, since you're seeing all the actions getting run in one test class, instead of several (based on how many triggers you write for your org).


I've tried using the standard workflows, but for some reason they dont work.


So I just make the basic workflow criteria(on Opportunity Products object) like: "Opportunity Product: Quantity not equal to null"  , and add field update action to update field "Status" on Opportunity Products. And then I set the formula for field value as following: "TEXT(Product2.Status__c)", because I want to take the value from field "Status" in Product and transfer its value to field "Status" on Opportunity Products. That doesnt work for some reason, i cant find out why. Any help on that?


P.s. thank you for test class. But I would rather avoid it, if I can make it work using workflows :)


Is the workflow "active"?  And is your field update formula pointing to the correct field?  Also, is that field on products populated, or is it just referencing a blank field?


If it runs every time you do an update, I usually just write "TRUE" for the evaluation criteria formula and set it to update everytime it's created or edited.  You might also consider not routing your formula directly through Products2, but instead routing it through PricebookEntry.Product2.[your field name].  I've heard of other people having problems when they route directly through Products2.[your field name] and often that extra step through the pricebook entry will resolve the issue.