【问题标题】:How can I use MockWebServer for Junit test cases of webclient?如何将 MockWebServer 用于 webclient 的 Junit 测试用例?
【发布时间】:2020-10-11 19:54:18
【问题描述】:

我有一个 spring-boot 应用程序,它使用 webclient 调用一些第三方 URL(比如说http://example.com/someUri)(我已经使用 application-dev.properties 在我的应用程序中注入这个 url 以实现松散耦合)并消耗响应并在我的应用程序中使用它。

这是我第一次为 webclient 编写测试用例。我在那里使用了@SprintBootTest。 我发现有两种方法可以通过模拟 api 调用并使其调用我的本地 url(将使用 url(http://localhost:{portNumber}/someUri) 来测试我的 webclient 与第三方 Api 调用来自我的测试属性文件:src/test/resources/application.properties),它将提供一些 mockedResponse 作为对我真实客户的回报:

  1. 使用 wiremock
  2. 使用 MockWebServer

考虑上面的代码以便更好地理解:

@Service
Class SampleService{
    
@Value("${sample.url}")
private String sampleUrl;

public String dummyClient() {
    String sample =webClient.get()
            .uri(sampleUrl)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .retrieve()
            .bodyToMono(String.class)
            .block();
    return sample;

    }
 }

应用程序-dev.properties:

sample.url:http://example.com/someUri

src/test/resouces/application.properties:

http://localhost:8090/someUri

测试类:

@SpringBootTest
public class sampleTestingClass {

@Autowired
private SampleService sampleService;

@Value("${sample.url}")
private String sampleUrl;

    public static MockWebServer mockWebServer = new MockWebServer();

    @BeforeAll
    static void setUp() throws IOException {
        mockWebServer.start(8090);
    }

    @AfterAll
    static void tearUp() throws IOException {
        mockWebServer.close();
    }

 HttpUrl url = mockWebServer.url("/someUri");
       
        mockWebServer
                .enqueue(
                new MockResponse()
                .setResponseCode(200)
                .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .setBody("Sample Successful")); 

      
        String sample = sampleService.dummyClient();
        assertEquals(sample ,matches("Sample Successful"));
    } 
}

但此代码不起作用。它给了我上面的错误:

java.lang.NullPointerException 

如果有人知道如何解决此问题以使用模拟 URL 实现我的单元测试,那将非常有帮助?提前致谢!

【问题讨论】:

    标签: unit-testing junit webclient spring-boot-test mockwebserver


    【解决方案1】:

    这是一个工作示例:

    @Component
    public class QuotesClient {
    
      private final WebClient webClient;
    
      public QuotesClient(WebClient.Builder builder, @Value("${client.baseUrl}") String baseUrl) {
        this.webClient = builder.baseUrl(baseUrl).build();
      }
    
      public JsonNode getData() {
        return this.webClient
          .get()
          .retrieve()
          .bodyToMono(JsonNode.class)
          .block();
      }
    }
    

    使用WebClient.Builder 是可选的。

    相应的测试可能如下所示:

    class QuotesClientTest {
    
      private QuotesClient quotesClient;
      private MockWebServer server;
    
      @BeforeEach
      public void setup() {
        this.server = new MockWebServer();
        this.quotesClient = new QuotesClient(WebClient.builder(), server.url("/").toString());
      }
    
      @Test
      public void test() {
    
        server.enqueue(new MockResponse()
          .setStatus("HTTP/1.1 200")
          .setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}")
          .addHeader("Content-Type", "application/json"));
    
        JsonNode data = quotesClient.getData();
        assertNotNull(data);
    
        System.out.println(data);
    
      }
    
    }
    

    如果您正在使用 WireMock, Spring Boot, and JUnit 5 搜索类似的设置,请查看链接指南。

    【讨论】:

    • 如果我没有构造函数怎么办,我在单独的配置文件中构建Webclient,并将@Autowired 注入我的service caler 类
    • 您可以为此创建一个新问题并添加代码示例吗?
    • 嗨,请检查一下,我创建了新问题stackoverflow.com/questions/69452223/…
    猜你喜欢
    • 2019-12-02
    • 2022-10-05
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多