6

I am trying to get coverage up for the following controller extension which I am using with Flow

public class ClosedLoopMarketingFlowExtension {

    private final Contact cont;
    private PageReference pageRef;
    private String fullRecordURL = URL.getSalesforceBaseUrl().toExternalForm(); 

    // Create Controller Extension
    public ClosedLoopMarketingFlowExtension(ApexPages.StandardController stdController) {
        this.cont = (Contact)stdController.getRecord();
    }


    // Create Instance of the flow (replace Closed_Loop_Marketing_Demo_Part_1 with your Flow API name)
    public Flow.Interview.Closed_Loop_Marketing_Demo_Part_1 myFlow {get; set;}

    public PageReference getFinishLocation(){
        String finishLocation;
        if(myFlow != null) {

            finishLocation = (String)myFlow.varLeadId; // Access flow varibale called varLeadId

        }

        if (finishLocation != null){

            pageRef= new PageReference(fullRecordURL + '/' +finishLocation);
            pageRef.setRedirect(true);
            return pageRef;

        } else {


            pageRef = new PageReference(fullRecordURL + '/' + cont.Id);
            pageRef.setRedirect(true);
            return pageRef;

        }


    }

}    

Here is my test class so far

@isTest
private class ClosedLoopMarketingFlowExtension_Test {


    @isTest static void test_method_one() {
        // Implement test code

        Account account = new Account( name = 'Test Account');
        insert account;

        Contact contact = new Contact( AccountId = account.Id, FirstName = 'Test', LastName = 'Me');
        insert contact;

        PageReference pageRef = Page.ClosedLoopMarketingDemo;
        Test.setCurrentPage(pageRef);

        ApexPages.StandardController ctr = new ApexPages.StandardController(contact);
        ClosedLoopMarketingFlowExtension ext = new ClosedLoopMarketingFlowExtension(ctr);

        ext.myFlow = new Flow.Interview.Closed_Loop_Marketing_Demo_Part_1(new Map<String, Object>());
        ext.myFlow.start();

        ext.getFinishLocation();




    }

}

This is my VFP too

<apex:page standardController="Contact" extensions="ClosedLoopMarketingFlowExtension" >
    <flow:interview name="Closed_Loop_Marketing_Demo_Part_1" 
                    interview="{!myFlow}" 
                    finishLocation="{!FinishLocation}">
                      <apex:param name="varContactId" value="{!Contact.Id}"/>


        </flow:interview>
</apex:page>

Cannot see to get coverage

 finishLocation = (String)myFlow.varLeadId; // Access flow varibale called varLeadId

        }

        if (finishLocation != null){

            pageRef= new PageReference(fullRecordURL + '/' +finishLocation);
            pageRef.setRedirect(true);
            return pageRef;

More info - this Extension is used to redirect (set FinishLocation) the user onto the Lead record which is created in the Flow

  • 1
    I'm not sure exactly what part you're having difficulty with? The bit you've highlighted seems like it should be covered by your test unless I'm missing something. Is varLeadId coming back null? Without seeing your Flow its hard to see why that might be. Have you tried setting it directly in your test? – Alex Tennant Jul 1 '15 at 22:16
  • Thanks Alex - Test coverage is 26%, it's not getting covered. – Michael Gill Jul 2 '15 at 10:28
5
+50

According to this blog post you will not be able to get the code coverage, he states that Salesforce has confirmed this. blog link:

**ANOTHER NOTE! You will NOT be able to get 100% test coverage when you link Flow to a controller like this. Because Flow requires user-interaction, if you try and reference the “flDemo” variable from the example above without first checking to see if it’s null (which it will be in the Unit Test), your test will fail. There is NO way right now (confirmed by Salesforce) to full test a Flow using this method…don’t pull your hair out trying.

A couple things I noticed about your test:
I would suggest changing your variable names so they are not the same as the sObject.
ext.myFlow.start(); Invokes an autolaunched flow or user provisioning flow. From the docs here. From another doc you are using a flow type flow not either of the above.

Flow Requires user interaction, because it has one or more screens, steps, choices, or dynamic choices.

This flow type doesn’t support wait elements.

A flow can be implemented with a custom button, custom link, direct URL, Visualforce page, or Salesforce1 action.

Autolaunched Flow Doesn’t require user interaction.

This flow type doesn’t support screens, steps, choices, or dynamic choices.

An autolaunched flow can be implemented any way that a flow can, as well as with a process action, workflow action (pilot), or Apex code.

User Provisioning Flow Provisions users for third-party services. A user provisioning flow can only be implemented by associating it with a connected app when running the User Provisioning Wizard. Provisions users for third-party services. For example, use this flow type to customize the user provisioning configuration for a connected app to link Salesforce users with their Google Apps accounts.

Here is another blog that suggests a workaround to this issue. Which is similar to Anshul's suggestion.

Recommendation: Codefriar posted A REUSABLE REDIRECT CONTROLLER FOR VISUALFLOWS although this will not get you 100% code coverage, it will limit the number of times you have code that can't be covered, especially if you redirect multiple flows this way.

Another update:

Try this:

public String getFinishId() { 
     return myFlow==null? cont.Id: myFlow.varLeadId; 
}

public PageReference getFinishPage(){
        PageReference pageRef = new PageReference('/' + getFinishId() );
        p.setRedirect(true);
        return p;
    }
  • That's fine, but I cannot get above 26% at the moment. – Michael Gill Jul 2 '15 at 10:28
  • @MichaelGill I think your best bet is to use the flow wrapper I just updated my answer with, in the long run this will at least keep your limited code coverage down to one class. – Jenny B Jul 2 '15 at 14:49
  • @MichaelGill see if my last update does the trick. – Jenny B Jul 2 '15 at 15:42
  • 1
    Thanks Jenny B for responding again. Wow Codefrair solution is just awesome, perfect! – Michael Gill Jul 2 '15 at 15:47
  • 1
    wouldn't you get better coverage with a ternary, though...? public String getFinishId() { return myFlow==null? cont.Id: myFlow.varLeadId; } .... – sfdcfox Jul 3 '15 at 19:51
1

As rightly mentioned by @JennyB, you would not be able to get optimum code coverage as your code is tightly coupled with flow. You would need to decouple it to ensure that your code doesn't depend on flow and you can then have a better code coverage. So you can break down your code as:-

(one of the quick fixes would be):-

public PageReference getFinishLocation(){
    String finishLocation;
    if(myFlow != null) {
        finishLocation = (String)myFlow.varLeadId; // Access flow varibale called varLeadId
    }else{
        finishLocation = cont.Id;
    }
    pageRef= new PageReference(fullRecordURL + '/' +finishLocation);
    pageRef.setRedirect(true);
    return pageRef;
}
  • Tried this, same. – Michael Gill Jul 2 '15 at 10:34
  • is it solved or are you still facing the problem? – Anshul Jul 2 '15 at 17:08
  • Solved. Pushing forward with Jenny's recommendation. Thank you again for taking time to respond. – Michael Gill Jul 2 '15 at 19:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.