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
Sujit KarandeSujit Karande 

How to write test class for multiple conditions in IF statement

Hi Everyone, 

Hope you're doing great. I stuck at some point where I am not aware of how we can write a tests for below piece of code from main class
 
Case obj = new Case();

if(

((obj.field1=='Yes' || obj.field2=='Yes') && checkNull(obj.field3))

||

((obj.field4=='Yes' || obj.field5=='Yes') && checkNull(obj.field6))

)

Note : checkNull() is method in the same class which checks for blank values

I have around 30 such conditions in IF statement and for few of conditions, it is showing that Tests are passed as I checked it in Developer Console

How could we tackle this? 

Thanks for your help in advance
Best Answer chosen by Sujit Karande
monsterloomismonsterloomis
Hi Sujit,

No problem. A couple of things:

I'm not sure how the class above is compiling given what's happening on lines 3-6, because I'd expect to see (for example):
if((obj.field1 == 'Yes' || obj.field2 == 'Yes') && checkNullValue(obj.field3))
...with "==" instead. "=" is an assigment operator, for setting values, while "==" is an equality operator.

Second, I don't see where "field1" is being set, and for that to work, there would need to be a field called "field1". With any sobject, you can do this kind of thing:
String yesOrNo = obj.get(field1);
System.assertEquals('Yes',yesOrNo); // an assertion like you might use in a test class.
...but for Case, I'd expect to see API names with this syntax. So, let's assume for the moment that you can get past those, or that I'm not understanding something. To simplify what I was explaining above a little, let's assume your class looks like this:
public class DeleteMe {
    
    public static Boolean validate(Case obj) {
        if((obj.Status == 'New' || obj.Origin == 'Web') && obj.Priority != NULL) {
            return true;
        } else {
            return false;
        }        
    }

}
To cover it, you'd want something like this:
@isTest
private class DeleteMeTest {

    // a good practice if you'll be creating a lot of test records; this will centralize it for you.
    @testSetup static void testCases() {
        Case testCase1 = new Case(
	        Status = 'New',
            Origin = 'Web',
            Priority = 'High',
            Subject = 'testCase1'
        );
		insert testCase1;
        Case testCase2 = new Case(
	        Status = 'New',
            Origin = 'Web',
            Priority = NULL,
            Subject = 'testCase2'
        );
        insert testCase2;
        
    }
    
    @isTest static void testValidatePass() {
        // get the record you set up in your @testSetup annotated method
        Case testCase1 = [SELECT Id, Status, Priority, Origin, Subject FROM Case WHERE Subject = 'testCase1' LIMIT 1];
		// use your test record to call the method in your class
        Boolean passOrFail = DeleteMe.validate(testCase1);
        System.assertEquals(true,passOrFail); // this case should return true, because it meets the criteria        
    }

    @isTest static void testValidateFail() {
        Case testCase2 = [SELECT Id, Status, Priority, Origin, Subject FROM Case WHERE Subject = 'testCase2' LIMIT 1];
		Boolean passOrFail = DeleteMe.validate(testCase2); 
        System.assertEquals(false,passOrFail); // this case should return false, because it doesn't meet the criteria        
    }
    
}
Tests take a bit of getting used to, but this should get you started, as long as you're also using resources like the link above to make sure you understand what's happening. Best of luck, and hope this helps.

Dave (monsterloomis)

 

All Answers

monsterloomismonsterloomis
Hi Sujit,

I'm assuming you're talking about coverage here, because I'm not entirely clear from your phrasing above - you say the tests are passed, but you want to know how to test it (?)

Assuming you're looking for coverage: if there is no choice but to include complex logic like this (and I would strongly recommend confirming that that is the case, and that there are no declarative solutions available) - then in order to cover the code, you need your test class to create case records that meet the conditions of each branch in your if/else logic. There are a variety of ways to efficiently create test records, so I would do a little research there before jumping in. Regardless of elegance, your test records will need to cover each condition individually.

I would also recommend covering checkNull explicitly by passing in some values and making assertions that it returns as expected, just for completeness and because of its frequent reuse in your code. If you insert records that meet the if/else criteria as suggested, you will achieve coverage for that method, but it's generally a better practice to cover things explicitly (IMHO).

Hope that helps!

Dave
Sujit KarandeSujit Karande
Hi @monsterloomis,

Thanks for getting back to me, that was very helpful. This is my actual class method definition
public static boolean validate (Case obj)
{
    if((obj.field1 = 'Yes' || obj.field2 = 'Yes') && checkNullValue(obj.field3))
    ||
    if
    if((obj.field4 = 'Yes' || obj.field5 = 'Yes') && checkNullValue(obj.field6))
   )
   return true;
   else
    {
          return false;
    }
}

 public static boolean checkNullValue(String value)
        {
            if(value==null || value.trim().length()==0)
            {
                return true;
            }    
            return false;
        }

Looking forward for your response.

Best,
Sujit
monsterloomismonsterloomis
Hi Sujit,

No problem. A couple of things:

I'm not sure how the class above is compiling given what's happening on lines 3-6, because I'd expect to see (for example):
if((obj.field1 == 'Yes' || obj.field2 == 'Yes') && checkNullValue(obj.field3))
...with "==" instead. "=" is an assigment operator, for setting values, while "==" is an equality operator.

Second, I don't see where "field1" is being set, and for that to work, there would need to be a field called "field1". With any sobject, you can do this kind of thing:
String yesOrNo = obj.get(field1);
System.assertEquals('Yes',yesOrNo); // an assertion like you might use in a test class.
...but for Case, I'd expect to see API names with this syntax. So, let's assume for the moment that you can get past those, or that I'm not understanding something. To simplify what I was explaining above a little, let's assume your class looks like this:
public class DeleteMe {
    
    public static Boolean validate(Case obj) {
        if((obj.Status == 'New' || obj.Origin == 'Web') && obj.Priority != NULL) {
            return true;
        } else {
            return false;
        }        
    }

}
To cover it, you'd want something like this:
@isTest
private class DeleteMeTest {

    // a good practice if you'll be creating a lot of test records; this will centralize it for you.
    @testSetup static void testCases() {
        Case testCase1 = new Case(
	        Status = 'New',
            Origin = 'Web',
            Priority = 'High',
            Subject = 'testCase1'
        );
		insert testCase1;
        Case testCase2 = new Case(
	        Status = 'New',
            Origin = 'Web',
            Priority = NULL,
            Subject = 'testCase2'
        );
        insert testCase2;
        
    }
    
    @isTest static void testValidatePass() {
        // get the record you set up in your @testSetup annotated method
        Case testCase1 = [SELECT Id, Status, Priority, Origin, Subject FROM Case WHERE Subject = 'testCase1' LIMIT 1];
		// use your test record to call the method in your class
        Boolean passOrFail = DeleteMe.validate(testCase1);
        System.assertEquals(true,passOrFail); // this case should return true, because it meets the criteria        
    }

    @isTest static void testValidateFail() {
        Case testCase2 = [SELECT Id, Status, Priority, Origin, Subject FROM Case WHERE Subject = 'testCase2' LIMIT 1];
		Boolean passOrFail = DeleteMe.validate(testCase2); 
        System.assertEquals(false,passOrFail); // this case should return false, because it doesn't meet the criteria        
    }
    
}
Tests take a bit of getting used to, but this should get you started, as long as you're also using resources like the link above to make sure you understand what's happening. Best of luck, and hope this helps.

Dave (monsterloomis)

 
This was selected as the best answer
Sujit KarandeSujit Karande
Hey Dave,

All your assumption were abosulutely correct and your solution works like a charm.

You saved my job :) Appreciate your help
. I will definately reach out to you in case I face any other issues

Cheers,
Sujit