【问题标题】:What are the pros & cons of 2 types of spring testing2种弹簧测试的优缺点是什么
【发布时间】:2019-05-25 03:59:46
【问题描述】:

在我目前的项目中,我们正在研究微服务(网络应用程序)。 在单元测试中,我们尝试覆盖 85-90% 的代码。我注意到使用 spring 进行测试的两种方法:

  • 注入控制器并直接调用其方法
  • 形成一个适当的请求,您可以在其中指定 cookie、标头...然后进行调用

此外,我们将无法使用 1 方法测试身份验证。

接下来应该使用哪些春季测试方式?每种类型的(缺点)优点是什么?



@RestController
class MyController {
    @PostMapping(path="/path")
    public String handle(@RequestBody MyRequest request) {
        //service invoked
        return "some value";
    }
}

JUnit 方法 #1


@LotsOfAnnotations
class ControllerTest1 {
    @Autowired
    private MyController myController;
    @Test
    public String verboseNameTest() {
        // Mock 3rd party calls
        ....
        // Form request
        MyRequest request = new MyRequest();
        // Invoke testing method
        myController.handle(request);
        // Assert
    }
}

JUnit 方法 #2


@LotsOfAnnotations
class ControllerTest2 {
    @Autowired
    private TestRestTemplate testTemplate;
    private MockRestServiceServer server;
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private WebApplicationContext webAppContext;

    @Before
    public void setup() {
        server = MockRestServiceServer.createServer(testTemplate.getRestTemplate());
        mockMvc = MockMvcBuilders.webAppContextSetup(this.webAppContext).build();
    }
    @Test
    public String verboseNameTest() {
        // Mock 3rd party calls
        ....
        // Form request
        String jsonStringRequest = "{}";
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                    .post("/path")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(jsonStringRequest);
        // Make a call
        MvcResult result = this.mockMvc
                    .perform(requestBuilder)
                    .andExpect(status().isOk())
                    .andReturn();
        // Assert
    }
}

【问题讨论】:

  • 对于我的项目,我们在服务层使用方法一,而在控制器测试中使用方法二。

标签: java spring-boot junit microservices spring-test


【解决方案1】:

据我所知,您需要了解何时模拟服务以及何时进行直接调用。

在您的第一种方法中,您直接调用 Web 服务,例如,假设您有一个庞大的代码库,并且同时有多个开发人员在工作,因此您会在类中不断更新,如果您想测试您的作品代码(这就是你使用 JUnit 的原因)然后你直接调用可能会导致错误/失败的测试用例,因为有人可能已经改变了一些东西。

第二种方法或模拟基本上通过模拟您的代码需要的其他服务来消除这种可能性,从而使您的代码测试更容易。

但是有些人会质疑,当你甚至没有测试整个事情时,模拟有什么用,这在一定程度上是正确的,但模拟的主要原因是只测试你的一段代码,而不考虑其他编码的服务是依赖的。此外,如果您谈到进行实际的服务调用,这应该是集成测试或端到端测试的一部分。

【讨论】:

  • 两者都以相同的方式模拟依赖项。模拟是指模拟另一个 HTTP 调用。有人可能会不断地更改代码。在响应改变之前,这两种方式都不会中断。此外,在我们的团队中,除了我之外的每个人都在使用 1 方法。是的,我们每天都在改变功能,但我们不会破坏响应。我们的不同测试通过了,但我问的是建议的做法是什么。未来我会面对什么?
猜你喜欢
  • 2010-09-10
  • 1970-01-01
  • 2014-01-24
  • 2013-01-30
  • 2015-01-11
  • 2010-09-06
  • 2010-10-29
  • 2011-07-12
相关资源
最近更新 更多