Tom Taylor
Tom Taylor

Reputation: 3540

How to return different value for a static method which is invoked during the flow during unit testing?

I'm trying to write unit testing for the following snippet.

class ABC {
    int getMyValue(final Activity activity) {
        if(MyClass.getInstance(activity).getValue() == 1) return 10;
        else return 20;
    }

    void doSomething() {
    }
}

I've tried something like this to test the doSomething function.

mABC = new ABC();

public void test_doSomething() {
   doReturn(20).when(mABC).getMyValue();
   //validate
}

How can I test getMyValue similarly? I would like to assert when the value is 1 it's returning me 10 and in all other cases, it's returning me 20.

I'm doing this in my android application. Is there any existing framework that can help me do this?

EDIT:

MyClass looks something like this

public class MyClass {

   private static Context mContext;
   public static getInstance(Context context) {
     mContext = context;
     return new MyClass();
   }

   private MyClass() {}

   public void getDreamValue() {
     Settings.Secure.getInt(mContext.getContentResolver(), "dream_val", -1);
   }
}

Upvotes: 1

Views: 761

Answers (1)

Reaz Murshed
Reaz Murshed

Reputation: 24211

You might consider modifying your MyClass as follows.

public class MyClass {

   private static Context mContext;

   // Create a private variable that holds the instance. 
   private Myclass instance;

   public static getInstance(Context context) {
     mContext = context;

     if (instance == null) 
         instance = new MyClass(); // Assign the instance here 

     return instance;
   }

   private MyClass() {}

   public void getDreamValue() {
     Settings.Secure.getInt(mContext.getContentResolver(), "dream_val", -1);
   }
}

Now, as you are using Robolectric, you can set the instance value to a mock as follows in your test class.

@RunWith(RobolectricTestRunner.class) 
public class ABCTest {

    @Mock
    MyClass mockInstance; 

    @Mock
    Context mockContext; 

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);

        // Set the mock instance for MyClass
        ReflectionHelpers.setStaticField(MyClass.class, "instance", mockInstance);
    }

    @Test
    public void testWhen1() {
       doReturn(1).when(mockInstance).getDreamValue();
       Assert.assertEquals(10, new ABC().getMyValue());
    }

    @Test
    public void testWhenNot1() {
       doReturn(2).when(mockInstance).getDreamValue();
       Assert.assertEquals(20, new ABC().getMyValue());
    }

    @After
    public void tearDown() {
        // Set the instance to null again to enable further tests to run 
        ReflectionHelpers.setStaticField(MyClass.class, "instance", null);
    }
}

I hope that helps.

Note: It looks like you are trying to provide a singleton instance of MyClass. Hence, you really should not create a new instance of MyClass in the getInstance function. I avoided creating a new instance each time, using the null check in my code.

Upvotes: 1

Related Questions