我在 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";
}
}
和测试:
@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"))
)
)));
}
}
问题是为什么我从真实服务而不是模拟中获取公司(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"
更新了 Test 类,删除了 setUp 并将 @Bean 更改为 @MockBean,但保留 @SpringBootTest 并且它可以工作:
@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"))
)
)));
}
}
最佳答案
首先,如果您只是测试应用程序的 Controller 部分,则应该使用 @WebMvcTest
注解而不是 @SpringBootTest
(您可以找到更多信息 here ) 。您可以像这样使用它:@WebMvcTest(CompanyController.class)
。
其次,为什么您在 setUp()
方法中的 MockMvc
遇到麻烦?您可以按照人们在注释和 @Autowire
MockMvc 中建议的那样删除该 setUp
方法。
最后,当您使用 Spring Boot 时,最好使用 @MockBean
而不是 @Mock
,它是 Spring 库中它的包装版本。
关于spring - Spring MVC 中的模拟服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45795854/