function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
amyhamyh 

Help with TestMethod

Hi, I'm begging for help 1 more time.

I have a trigger that compiles fine (thanks Drew). I cannot deploy it to the server, because of an error I get
that points to my testmethod (even though, I can run my test class and deploy it to the server). Could you
give me any insight to creating these test classes? Thank you.

trigger CreateCaseAfterShippingConfirmsOrder on SFDC_520_QuoteLine__c(after insert, after update)
{
    List<Id> myIDs = new List<Id>{}; //use this to store all the Product2 Ids to query for
       
    for (SFDC_520_QuoteLine__c obj : Trigger.new)
        {
            myIDs.add(obj.Product2__c) ;
        }
    //Need to move the SOQL Query out of the FOR LOOP otherwise you'll hit a governor limit in some scenarios
    Map<Id,Product2> productMap = new Map<Id,Product2>([select name  from Product2 where ProductCode IN :myIDs]);
   
    //Now loop through records again
    for (SFDC_520_QuoteLine__c obj : Trigger.new)
    { 
         if (obj.Shipping_Confirms_Order__c == True)
             {
                   Case newCase = new Case(
                     //Use the Map to get the Product2 Name out of the Map generated by the SOQL query above
                     Description = productMap.get(obj.Product2__c).Name + ' ' + obj.Description__c,
                     Subject = 'New Data Production Project',
                     Status = 'Not Started',
                     Product__c = 'Custom Data',
                     Priority = 'Sev-4 (when resources allow)',
                     Origin = 'Web'
                     );
                     insert newCase;
             }
     }
 }         


@isTest
public class TestClass {
  static testMethod void myTest() {
      SFDC_520_Quote__c q = [select id from SFDC_520_Quote__c where name='08-30287'];
    SFDC_520_QuoteLine__c LI = new SFDC_520_QuoteLine__c(Quote__c = q.ID,Shipping_Confirms_Order__c= true);
    insert LI; //this line is where the error is when I try to deploy the trigger
 }
}
Drew1815Drew1815
When writing test methods, its recommended that within the test method itself, you create all data required for the test. In your example, you query for a specific SFDC_520_Quote__c record that probably exists in your development or sandbox environment. But that record might not exist in your destination/production org. That might not be your exact error scenario , but its definitely a best practice to create all data you need within your test method itself.

Secondly, you could add some exception handling into your test method with standard Try/Catch syntax.

Are there validation rules that are failing on insert since you only are populating 2 fields? Just a thought. 

How are you trying to deploy the apex? Through the Force.com IDE? Or Ant script? The deployment wizard should output a more detailed error message. If you have that information, please provide it here and I'll try to help resolve the issue.

Thanks,
Andrew
amyhamyh
Thanks again Drew,

I am using the Force.com IDE

I right-click on my Class and click "Run Tests", that seems to go fine. "100% covered"

I then tried to right-click "Deploy to Server" on the trigger itself. Apply Action: "Overwrite"
Failures and Warnings TestClass.myClass.myTest line 5 column 5 which is the Insert Line

I was not able to create a "new" Sales Order (SFDC_520_Quote__c) in my test class because I couldn't get past
all of the required fields (not knowing any ID's say for the Account). My only environment is the Production one
unfortunately.


JimRaeJimRae
You should create all of the objects necessary to test your object, that way your testmethod would work in both test and production.  You must have some development environement that Eclipse is pointing to, since you can't create directly in production.  I have test cases where I created the User, pricebook, product, Account, Opportunity and OpportunityLine item so I could fire my Opplineitem trigger.  Remember, when you create these in a testmethod, they are not saved in the database.

If you just need an account to create the sales order on, it should be pretty straightforward.
amyhamyh
Thank you Jim,

One follow up question regarding your post. Where in Eclipse do I look for where my environment is pointing to? Something does seem off because when I try to deploy my trigger, I see some text that says "No differences detected"....which there are many.

Failures and warnings shows the error on the insert line

Code coverage results says 0 lines not tested %100 covered (which sounds good)

thanks for your help.
JimRaeJimRae
Assuming you have the latest plugin installed, you can right click on your project, select "Properties" and in the Properties window, select the Force.com element.  You should see a box called Organization Settings with your Username and password, plus and "environment".  If it says "Sandbox" you are attached to a development instance, if it says Production/Developer Addition then you need to  go by the username you are using. 

when you run the deploy to server, you should see the same box, if your environment there is set to the same environment as your project, then you won't see any changes.
For my organization, I develop in the "Sandbox" and deploy to "Production".
amyhamyh
Hi Drew,

Quick question for you. I looked at the error logs and found out that the trigger would not deploy
because of an error on this line from your changes.

Error: Description = productMap.get(obj.Product2__c).Name + ' ' + obj.Description__c,

Works: Description = obj.Description__c,

The productMap is sourced by your code change:
Map<Id,Product2> productMap = new Map<Id,Product2>([select name  from Product2 where ProductCode IN :myIDs]);

Any thoughts on getting the "Name" value from this new map?

thanks,
Paul
Drew1815Drew1815
What is being stored in the SFDC_520_QuoteLine__c.Product2__c custom field? Is that a lookup reference to the Product2 object? Or does it store the ProductCode value? The way your Map collection is populated is with this line:

Map<Id,Product2> productMap = new Map<Id,Product2>([select name  from Product2 where ProductCode IN :myIDs]);

and notice that the where clause is by ProductCode. Is that the right field to filter by? Or should it be Id?

I also recommend adding System.debug messages in your code to understand where the error is thrown.

I am wondering if your deployment is failing since the Map is not populated with the right data (per that inline SOQL query) and therefore when you perform the "get" operation on the Map, it is not retrieving a value and returning null instead.

Also, please be aware that 100% code coverage does not necessary mean that the code executes properly in all business scenarios. It is recommend to make sure all scenarios , both positive and negative test cases are evaluated through test methods.

Thanks.


amyhamyh
Thanks Drew,

Your right that the select clause should be using the ID field. That makes sense to me, but I still get the error.
Your suspicion on the error was exactly right, I'm now guessing that I'm not filling the ProductMap correctly. I'll have
to learn how to debug Apex code.

Run Failures:
  TestClass.myTest System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CreateCaseAfterShippingConfirmsOrder: execution of AfterInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.CreateCaseAfterShippingConfirmsOrder: line 21, column 68
Drew1815Drew1815
Another thing I noticed in your test method is that you do not set the Product2__c field on the SFDC_520_Quote__c record you are created in your test. Therefore, when the trigger runs, it won't have a Product2__c ID populated, the Map won't contain any records, and you will get a NullPointerException when you access the Name field on the Map.

I think the trigger needs to handle when the field Product2__c is null better. And that the test method needs to populate the Product2__c field on the QuoteLine.
amyhamyh
Drew, that was it!

Setting the field in the test method was the key.

Works great now. Thanks so much!!