mangkool
mangkool

Reputation: 308

Mockito wanted but not invoked utility class

I am making a unit test for class in my app, it just a simple class and I thought i did everything right but the test failed saying

Wanted but not invoked: mContextWeakReference.get(); -> at rahmat.com.app.utility.backwardcompatibility.StringResourceUtilTest.getString(StringResourceUtilTest.java:40) Actually, there were zero interactions with this mock.

this is the class to be tested

public class StringResourceUtil {

private static StringResourceUtil sInstance;

private WeakReference<Context> mContextWeakReference;

public static StringResourceUtil getInstance() {
    return sInstance;
}

@Inject
public StringResourceUtil(Context context) {
    mContextWeakReference = new WeakReference<>(context);
    sInstance = this;   //NOSONAR
}

public String getString(int resId) {
    return mContextWeakReference.get().getString(resId);
}}

this is unit test I made

public class StringResourceUtilTest {


private StringResourceUtil mResourceUtil;

@Mock
private Context mContext;

@Mock
private WeakReference<Context> mContextWeakReference;

@Before
public void setUp(){
    MockitoAnnotations.initMocks(this);
    mResourceUtil = new StringResourceUtil(mContext);
}


@Test
public void getString() {
    int resId = 123;
    mResourceUtil.getString(resId);
    verify(mContextWeakReference).get().getString(eq(resId));
}}

any help would be much appreciated, thanks

Upvotes: 2

Views: 1180

Answers (2)

Pavneet_Singh
Pavneet_Singh

Reputation: 37414

Your StringUtil class is always creating a new object of mContextWeakReference object and even if you are making it, it won't inject automatically ( for that you use injectMock but no use here, since new object creation always happens internally).

public class StringResourceUtilTest {


    private StringResourceUtil mResourceUtil;

    @Mock
    private Context mContext;

    @Before
    public void setUp(){
        MockitoAnnotations.initMocks(this);
        mResourceUtil = new StringResourceUtil(mContext);
        // setup mock return type
        // mock objects are not real,so need to moeck the behavior of method as well
        when(mContext.getString(R.string.a123)).thenReturn("123");
    }


    @Test
    public void getString() {
        int resId = R.string.a123;
        // check the return type
        assertEquals("123",mResourceUtil.getString(resId));
    }
}

Note: To verify the internal working, read

What is the difference between mocking and spying when using Mockito?

Upvotes: 1

borino
borino

Reputation: 1750

Because you creating mContextWeakReference = new WeakReference<>(context); in constructor, it will never been a mock in StringResourceUtil.

You can set prepared mock mContextWeakReference by using

org.springframework.test.util.ReflectionTestUtils.setField(mResourceUtil , "mContextWeakReference", mContextWeakReference); 

Otherwise you should modifying StringResourceUtil class to be a testable

Upvotes: 0

Related Questions