简体   繁体   中英

Testing a map contained in a mocked class

I am trying to test a ExampleController class which works kind of like a facade for my POJO Example class.

I started to write a InstrumentedTest for the ExampleController because it works with Greenrobots EventBus, and got a NullPointerException when I tried to retrieve values which are stored in a Map in my Example class.
I use Mockito v2.7.19 , Espresso 2.2.2 and JUnit 4.12 .

I recreated my problem in a Unit test with the following example setup:

class Example {
    private HashMap<Integer, String> map;
    Example(){ map = new HashMap<>(); }
    //getter and setter for map
}

class ExampleController {
    private Example example;
    ExampleController(Example example){ this.example = example; }

    public HashMap<Integer, String> getMap(){ return example.getMap(); }
}

Test class:

class ExampleControllerTest {
    ExampleController exampleController;

    @Before
    public void setUp() throws Exception {
        Example example = mock(Example.class);
        exampleController = new ExampleController(example);
    }

    @Test
    public void testPutThingsInMap() throws Exception {
        HashMap<Integer, String> map = exampleController.getMap();
        map.put(1, "Test");
        exampleController.getMap().putAll(map);

        assertEquals(1, exampleController.getMap().size());
    }
}

When I run the test class I get the following output:

java.lang.AssertionError: 
Expected :1
Actual   :0

As I am relatively new to testing, I don't know where I went wrong. When I search for unit testing lists, I only find tests for lists that are not contained in an object.

You can't use the "getMap" method like that, because you mocked the Example class in the ExampleController. You could fix this by adding the following in the before-method:

HashMap<Integer, String> mapInMock = new HashMap<>();
when(example.getMap()).thenReturn(mapInMock);

This way you're telling the mocked Example to return that hashMap when the getter is called.

I can't find it immediately in the javadoc, but debugging the test shows that the map a new map is returned after each call to exampleController.getMap(). That explains why you can't get anything in the map and retrieve it afterwards with your exampleController.

Besides this being the solution you can wonder if you actually need to mock the Example class. You could also just instantiate it, unless you actually want to mock some parts of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM