简体   繁体   中英

Impossible to write integration test controller with DAO mock?

I become crazy, I tried all possible combination of various test Runners and possibles annotation for testing, the nearest solution of my need is following :

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyApplication.class})
@WebAppConfiguration
public class MyControllerTest {

    MockMvc mockMvc;

    // My DAO is an interface extending JpaRepository
    @Mock
    MyDAO myDAO;

    @Autowired
    WebApplicationContext webApplicationContext;

    @Before
    public void setUp() throws Exception {
        List<MyItem> myItems = new ArrayList(){{
            // Items init ...
        }}
        Mockito.when(myDAO.findAll()).thenReturn(myItems);
        /* Other solution I tried with different annotations: 
        * given(myDAO.findAll()).willReturn(myItems);
        * this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
        */
        this.mockMvc = webAppContextSetup(webApplicationContext).build();

    }

    @After
    public void tearDown() throws Exception {
//        Mockito.reset(myDAO);
    }

    @Test
    public void getItems() {
        String res = mockMvc.perform(get("/items"))/*.andExpect(status().isOk())*/.andReturn().getResponse().getContentAsString();
        assertThat(res, is("TODO : string representation of myItems ..."));
        assertNull(res); // For checking change in test functionning
    }
}

I well enter in debug mode in my controller method, in service method but when I see DAO type, it is not a Mock and findAll() always return empty ArrayList(), even when I do :

Mockito.when(myDAO.findAll()).thenReturn(myItems);

I do not have exception raised, my DAO is not mocked and I don't know how to do despite all tuto I found. The nearest tuto of my need I found was this Unit Test Controllers with Spring MVC Test but not enought because he wants mock service injected into controller in order to test controller, I wand to mock DAO injected into real Service injected into Controller (I want to test Controller + Service).

It seems to me that I already did that by using an annotation on the test class which specified what class had to be instanciate by spring application in test mode and what class had to be mocked but I don't remember '-_-.

Need your help, its making me crasy !

Thank you very much !!!

For @Mock annotation you need additional initialization:

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

Or change runner to the @RunWith(MockitoJUnitRunner... , but not sure about spring context initialization in this case.

I finally did like that (but not satisfied because it does not mock HSQLDB DataBase, it creates a test one), whereas I wanted to mock DAO :

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MySpringApplication.class})
@WebAppConfiguration
public myTestClass {
    MockMvc mockMvc;

    @Autowired
    ItemDAO itemDAO;

    @Autowired
    WebApplicationContext webApplicationContext;

    @Before
    public void setUp() throws Exception {
        this.mockMvc = webAppContextSetup(webApplicationContext).build();
    }

    @After
    public void tearDown() throws Exception {
        itemDAO.deleteAll();
    }

    @Test
    public void testMethod() {
        // DB init by saving objects: create a item and save it via DAO, use real test DB

        // Only mocking about rest call:
        String res = mockMvc.perform(get("/items")).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
    }

}

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