hc0re
hc0re

Reputation: 1986

Mocking a class inside the tested method

I have a problem with a class I have to mock.

The tested method looks like this:

testedMethod(Date from, Date to, Set set1, Set set2, SomeContext context) { method body };

Now inside the method body, there is a class used. The usage looks like this:

List list = ComponentsFetcher.getComponent(String string1, context, from, to, String string2);

The whole tested method (a bit simplified) looks like this:

public static final long testedMethod(Date from, Date to, Set set1, Set set2, SomeContext context) {

    long returnedLong = 0;

    List list1 = ComponentsFetcher.getComponent(String string1, context, from, to, String string2);
    List list2 = ComponentsFetcher.getComponent(String string3, context, from, to, String string4);

    returnedLong = TestedMethodsClass.anotherMethod(from, to, set1, set2, list1, list2

    return returnedLong;

};

This ComponentsFetcher.getComponent() method is doing many things, but ALL I need here is to get this list, I know how is this list looking like, I can simply create it and use it later in the tested method.

So I am wanting to mock the ComponentsFetcher.getComponent() like this:

private void mockComponentsFetcher(Date from, Date to, ComponentsContext context, List list1, List list2) throws SomeBusinessException {
    Mockito.mock(ComponentsFetcher.class);
    Mockito.when(ComponentsFetcher.getComponent(string1, context, from, to, string2)).thenReturn(list1);
    Mockito.when(ComponentsFetcher.getComponent(string3, context, from, to, string4)).thenReturn(list2);
    }

Finally, the @Test method:

@Test
    public void testTestedMethod() throws ParseException, SomeBusinessException {
        //given
        Date from = DateHelper.getDate(2011, 07, 03);
        Date to = DateHelper.getDate(2012, 07, 03);
        Set set1 = null; // can be null
        Set set2 = DateHelper.getDate(2011, 07, 03);
                Date day = DateHelper.getDate(2011, 07, 03);

        List list1 = getList(new Date[]{
                                // contents of the list
               });
        List list2 = getList(new Date[]{
                                // contents of the list
               });

        //mock
        ComponentsContext context = mockContext(day);

// This context REALLY DOESNT matter, it is mocked just for the method to run.

// here is the main problem, I have no idea how to use this mocked ComponentsFetcher, while it is used INSIDE the testedMethod

        mockComponentsFetcher(from, to, context, list1, list2);
        //when
        long months = TestedMethodsClass.testedMethod(from, to, set1, set2, context);
        //then
        long awaited = 12;
        assertThat(months).isEqualTo(awaited);
    }

But it ain't working at all...

Upvotes: 1

Views: 965

Answers (1)

Hilikus
Hilikus

Reputation: 10331

You can't mock static methods using mockito. If you want to stay with mockito, try to redesign your class so that the method is not static and then mock the actual instance of the object.

For unit testing's sake, it is always preferred to avoid global singletons (due to exactly the problem you had) and rely instead on dependency injection. What this means is that you would create your ComponentsFetcher somewhere else in the code and pass it to your class under test, probably at construction time. This will allow you to inject a mocked one when preparing your unit test and use a real one when in production

Upvotes: 2

Related Questions