Spring MVC 中的模拟服务

2023-12-19

我在 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"))
                    )
            )));
}

}


首先,如果您只是测试应用程序的控制器部分,您应该使用@WebMvcTest注释而不是@SpringBootTest(您可以找到更多信息here https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests)。你可以这样使用它:@WebMvcTest(CompanyController.class).

其次,你为什么会遇到麻烦MockMvc in setUp()方法?你可以删除它setUp人们在评论中建议的方法和@Autowire模拟Mvc。

最后,由于您使用的是 spring boot,所以最好使用@MockBean代替@Mock这是它在 spring 库中的包装版本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring MVC 中的模拟服务 的相关文章

随机推荐