0

I have written a trigger ans test class. New to coding so could do with someone casting their eye over the test class as it doesn't seem to hit the 75% code coverage.

APEX TRIGGER

trigger CreateQuote on Opportunity (after insert) {
    List<Id> oppIdsList = new List<Id>();
    List<Quote> quoteList = new List<Quote>();
    for (Opportunity o : Trigger.new) {
        oppIdsList.add(o.id);
    }
    Opportunity[] oppList = [SELECT
                                 name,
                                 id,
                                 account.billingStreet,
                                 account.billingCity,
                                 account.billingState,
                                 account.billingCountry
                             FROM Opportunity
                             WHERE id IN :oppIdsList and Type = 'New Client'];
    for (Opportunity o : oppList) {
        Quote q = new Quote();
        q.name = 'Quote-' + o.name;
        q.opportunityId = o.id;
        q.billingStreet = o.account.billingStreet;
        q.billingCity = o.account.billingCity;
        q.billingState = o.account.billingState;
        q.billingCountry = o.account.billingCountry;
        quoteList.add(q);
    }
    insert quoteList;
}

My Test Class

@isTest 

public class TestCreateQuote 
{
Static testMethod void TestCreateQuote(){
    Account a = [select Id from Account limit 1];
    Opportunity o = new Opportunity();

    o.Accountid = a.id;
    o.Name = 'test';
    o.StageName = 'Prospecting';
    o.CloseDate = date.today();
    o.Project_Type_test__c = 'Training';
    o.Remuneration_Model__c = 'Fees Only';
    o.Type = 'New Client';
    o.NextStep = 'Test';
    o.LeadSource = 'Business Development';
    insert o;

    }
}

Result of the test:

enter image description here

2
  • Hi and welcome to the site. I have edited your question so that there is formatting in the trigger code. None of the logic has changed, I just added spaces and tabs to help other people understand your code a little easier
    – BarCotter
    Commented Feb 13, 2015 at 13:07
  • Do you know what parts of your trigger are not covered by the test?
    – BarCotter
    Commented Feb 13, 2015 at 13:09

4 Answers 4

3

The exception is from not being able to select an account from the system as SeeAllData is false (by default). The best solution is to create an Account and insert into the database.

    @isTest 

    public class TestCreateQuote 
    {
    Static testMethod void TestCreateQuote(){
//NOTE:You may need to add extra data here dependent on triggers and validation rule criteria.
        Account a = new Account(name='acc1');
    insert a;
        Opportunity o = new Opportunity();

        o.Accountid = a.id;
        o.Name = 'test';
        o.StageName = 'Prospecting';
        o.CloseDate = date.today();
        o.Project_Type_test__c = 'Training';
        o.Remuneration_Model__c = 'Fees Only';
        o.Type = 'New Client';
        o.NextStep = 'Test';
        o.LeadSource = 'Business Development';
        insert o;

        }
    }
0

somehow I managed to past that using another profile without noticing... now I cant comment on the post! Anyway, here is the message received about the code coverage failing.

Error message

1
  • I have updated your question to include the error message. Feel free to delete this answer as it is not an actual answer.
    – BarCotter
    Commented Feb 13, 2015 at 13:34
0

Test methods don't have any access to data in your org so the line below in your test class is throwing the error "List has no rows for assignment to SObject". This error is stopping the test from running and is why you are not seeing any code coverage.

Account a = [select Id from Account limit 1];

One solution would be to use the SeeAllData=true annotation but this would mean any org that needs to run this test must have an account setup.

A much better approach is to create all the records in the test. In the code below the account is being setup as part of the test. Ive also included code that verifies that the quote is being created correctly.

@isTest 
public class TestCreateQuote 
{
Static testMethod void TestCreateQuote(){
    Account a = new Account(name='Test Account', billingStreet='Test', billingCity='Test', billingState='Test', billingCountry='Test');
    insert a;
    Opportunity o = new Opportunity();

    o.Accountid = a.id;
    o.Name = 'test';
    o.StageName = 'Prospecting';
    o.CloseDate = date.today();
    o.Project_Type_test__c = 'Training';
    o.Remuneration_Model__c = 'Fees Only';
    o.Type = 'New Client';
    o.NextStep = 'Test';
    o.LeadSource = 'Business Development';
    insert o;

    List<Quote> quotes = [select Id, billingStreet, billingCity, ... from Quote where opportunityId =:o.Id];
    System.assertEquals(1, quotes.size());
    for (Quote q : quotes) {
        System.assertEquals(a.billingStreet, q.billingStreet);
        System.assertEquals(a.billingCity, q.billingCity);
        ...
    }
}

You should also consider having a test that creates an Opportunity with the Type set to something other than 'New Client' to verify that no quote is created.

0

A variation on @BarCotter's excellent answer is

@isTest 
public class TestCreateQuote {
static void TestCreateQuote(){
    Account a = new Account(name='Test Account', billingStreet='Test', billingCity='Test', billingState='Test', billingCountry='Test');
    insert a;
    List<Opportunity> oList = new List<Opportunity> {
      new Opportunity(accountId = a.id, name = '00Test', type = 'New Client',..),
      new Opportunity(accountId = a.id, name = '01Test', type = 'Old Client',..)};
    insert oList;

    List<Quote> quotes = [select Id, billingStreet, billingCity, ... from Quote where opportunityId IN :oList];
    System.assertEquals(1, quotes.size(),'only 1 quote is from Oppo: New Client');
    for (Quote q : quotes) {
        System.assertEquals(a.billingStreet, q.billingStreet);
        System.assertEquals(a.billingCity, q.billingCity);
        System.assertEquals(q.opportunityId,oList[0].id); // quote assigned to expected Oppo
        ...
    }
}

I find if you create all the test objects in lists, then you can

a) verify that your trigger handles multiple sobjects in trigger.new

b) you can run more tests with less code

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .