I have a problem with mocking service in Spring MVC:
@Controller
public class CompanyController {
@Autowired
private CompanyService companyService;
@Autowired
private CompanyRelationService companyRelationService;
@GetMapping({"/", "/companies"})
public String displayCompanies(Model model) {
model.addAttribute("company", new Company());
List<Company> companies = companyService.findAll();
model.addAttribute("companies", companies);
return "companies";
}
}
and test:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class CompanyTests {
@Autowired
private WebApplicationContext webApplicationContext;
@Mock
CompanyService companyServiceMock;
private MockMvc mockMvc;
@Before
public void setUp() {
Mockito.reset(companyServiceMock);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldListAllCompanies() throws Exception {
Company company1 = new Company("company1", new Address());
Company company2 = new Company("company2", new Address());
when(companyServiceMock.findAll()).thenReturn(Arrays.asList(company1, company2));
mockMvc.perform(get("/companies"))
.andExpect(status().isOk())
.andExpect(view().name("companies"))
.andExpect(model().attribute("companies", hasSize(2)))
.andExpect(model().attribute("companies", hasItem(
allOf(
hasProperty("name", is("company1")))
)))
.andExpect(model().attribute("companies", hasItem(
allOf(
hasProperty("name", is("company2"))
)
)));
}
}
The question is why I get companies from real service instead of mock (company1, company2):
java.lang.AssertionError: Model attribute 'companies'
Expected: a collection containing (hasProperty("name", is "company1"))
but: hasProperty("name", is "company1") property 'name' was "companyFromRealService",
hasProperty("name", is "company1") property 'name' was "CompanyFromRealService2"
Updated Test class, removed setUp and changed @Bean into @MockBean, but remain @SpringBootTest and it works:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CompanyTests {
@MockBean
private CompanyService companyServiceMock;
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(roles = "ADMIN")
public void shouldListAllCompanies() throws Exception {
Company company1 = new Company("company1", new Address());
Company company2 = new Company("company2", new Address());
when(companyServiceMock.findAll()).thenReturn(Arrays.asList(company1, company2));
mockMvc.perform(get("/companies"))
.andExpect(status().isOk())
.andExpect(view().name("companies"))
.andExpect(model().attribute("companies", hasSize(2)))
.andExpect(model().attribute("companies", hasItem(
allOf(
hasProperty("name", is("companyFromRealService1")))
)))
.andExpect(model().attribute("companies", hasItem(
allOf(
hasProperty("name", is("companyFromRealService2"))
)
)));
}
}
get("/companies")? I guess it calls real service. Replace the call with mock results@Beforemethod and put@Autowiredon theMockMvcfield and restart your test.@AutoConfigureMockMvcto your test class.@Mockwith@MockBean.