1

I need to fix some Apex test coverage and I have the the following issue:

I have my controller class like this:

public with sharing class someClass{

      public Boolean isTestClass = false

      @AuraEnabled
      public static String myMethod(String a, String b){
             if(isTestClass == true){
                return ('Covered Line')
             }else{
                return ('Covered Line')
             }
      }
}

And I want my Test class like this:

@isTest
public class myTestClass{

//SOME TEST SETUP BELOW @TestSetUp

      public static testmethod void myTest(){
             // here I want to do this
             someClass sc = new someClass();
             sc.isTestClass = true;
             sc.myMethod('a','b')
             sc.isTestClass = false;
             sc.myMethod('a','b')
      }
}

So it’s pretty much instantiating my controller class, set up a value and run two different tests one with false and one with true, so both if cases are covered but I have the following issues:

First, I can’t access the method from the instance because it’s an static method.

Second, the isTestClass variable is nonexistent inside myMethod().

How can I fix these two problems?

Btw, I can not change the class someClass that much and not even its methods. I was trying to send the isTestClass value over the myMethod parameter, but it affects other process that use that method and I can't do that.

2 Answers 2

1

Not recommending code like this but this will fix (at least in allowing compilation) one problem:

public static Boolean isTestClass = false;

and this the other:

public static testmethod void myTest(){
    someClass.isTestClass = true;
    someClass.myMethod('a','b')
    someClass.isTestClass = false;
    someClass.myMethod('a','b')
}

Do read up on this subject e.g. Static and Instance Methods, Variables, and Initialization Code.

6
  • Could use overloading so the existing code calls the new method with this boolean set false... also should recommend replacing testMethod with @IsTest.
    – Phil W
    Mar 15, 2022 at 19:32
  • But then this is all very hacky, so leave it as ugly as you suggested!
    – Phil W
    Mar 15, 2022 at 19:35
  • It Worked but why would you recommend it Im curious Mar 15, 2022 at 19:39
  • @PhilW yep I was doing that but then boss told me not to change those parts Mar 15, 2022 at 19:40
  • 2
    Hi @PhilW, I was thinking one learning step at a time. Just gave Derek F's answer a +1 though for a more complete explanation.
    – Keith C
    Mar 15, 2022 at 20:56
4

In general...

  • Static variables can be accessed in static methods
  • Instance variables can be accessed in non-static methods (i.e. instance methods)
  • Static variables and methods are accessed in non-static contexts by using <class name>.<static variable or method name> (if the visibility modifier allows it)

The problem you're running into is that you/your class is trying to mix static and non-static contexts.

public class StaticExample{
    public static Boolean staticFlag;
    public Boolean instanceFlag;

    // This is a "static constructor", which allows you to call static methods of this
    //   class and static variables of this class without prefixing it with the class name
    static{
        staticFlag = false;
    }

    public static Integer doThing(){
        // likewise, static methods can access static variables without prefixing it
        //   with the class name
        if(staticFlag){
            return 1;
        }

        // static methods cannot access instance variables
        // to do that, you need to make a new instance of the class

        // will error out when you try to save the class
        // if(instanceFlag != null){ return 3; }

        // will successfully save
        StaticExample classInstance = new StaticExample();
        if(classInstance.instanceFlag){
            return 3;
        }

        return 2;
    }

    // Normal constructors (and methods) can access instance variables directly
    public StaticExample(){
        instanceFlag = true;

        // Static variables are accessed using the class name in non-static methods
        if(StaticExample.staticFlag){
            system.debug('static flag is true');
        }else{
            system.debug('static flag is false');
        }
    }

    // Same deal with instance methods
    public void doInstanceThing(){
        system.debug('static flag is ' + (StaticExample.staticFlag ? 'true', 'false'));

        system.debug('instance flag is ' + (instanceFlag ? 'true', 'false'));
    }
}

Probably the easiest way to fix this problem is to make isTestClass a static (so that you're not mixing contexts), but using a flag like this to test for a test context is a red flag.

You should also be using @isTest instead of the testMethod keyword

old way (deprecated)

static testmethod void myTest()

current way

@isTest
static void myTest()

One last piece of advice. You generally don't want to try to run through multiple branches of if/else in a single test method. A failure in one part prevents the subsequent parts from being run. Instead, you should break them out into separate test methods.

1

You must log in to answer this question.

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