unit-testing - 如何将 MockWebServer 用于 webclient 的 Junit 测试用例?

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

我有一个 spring-boot 应用程序,它使用 webclient 调用一些第三方 URL(比如说 http://example.com/someUri )(我已经使用 application-dev.properties 在我的应用程序中注入(inject)这个 url 以实现松散耦合)并消耗响应并使用它在我的应用程序中。
这是我第一次为 webclient 编写测试用例。我在那里使用了@SprintBootTest。
我发现有两种方法可以通过模拟 api 调用并使其调用我的本地 url(将使用 url(http://localhost:{portNumber}/someUri) 来测试我的 webclient 与第三方 Api 调用来自我的测试属性文件:src/test/resources/application.properties),它将提供一些 mockedResponse 作为返回给我的真实客户:

  • 使用 线模
  • 使用 模拟网络服务器

  • 考虑上面的代码以更好地理解:
    @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/resources/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 实现我的单元测试,那将非常有帮助?提前致谢!

    最佳答案

    这是一个工作示例:

    @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 搜索类似的设置,看看链接的指南。

    关于unit-testing - 如何将 MockWebServer 用于 webclient 的 Junit 测试用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62506206/

    相关文章:

    python - Django REST UnitTest 没有提交文件

    junit - 如何在为静态方法编写junit时从静态方法模拟实例方法调用?

    mysql - Junit 在使用 session.save 但不在 MySQL 数据库表中插入数据时成功,尽管我也尝试刷新 session

    java - 点击(160.0,120.0)无法完成! (java.lang.SecurityException : Injecting to another application requires INJECT_EVENTS permission)

    .net - VB.net异步http POST接收部分内容

    c# - 如何为WebClient()设置暂停功能?

    c# - 我应该模拟还是伪造我的存储库?

    unit-testing - 单元测试抽象类和/或接口(interface)

    spring - 使用 WebClient 发送 byteArray

    javascript - 使用 apply、call 或 bind 方法在 JavaScript 中进行依赖注入(inject)