JUnit テストで MockWebServer ポートを WebClient に設定するにはどうすればいいですか? 質問する

JUnit テストで MockWebServer ポートを WebClient に設定するにはどうすればいいですか? 質問する

私は、Bean として自動配線される を使用していspring-bootます。WebClient

問題:junit統合テストを書くときに、 okhttp を使用する必要がありますMockWebServer。このモックは常にランダムなポートで起動します (例: ) localhost:14321

もちろん、 myWebClientにはリクエストを送信する固定 URL があります。 この URL はapplication.propertiesのようなパラメータで指定できるwebclient.url=https://my.domain.com/ため、テストでそのフィールドをオーバーライドできますjunit。 ただし、静的にのみです。

質問:リクエストが常にモック サーバーに送信されるように、WebClient内部の Beanをリセットするにはどうすればよいですか?@SpringBootTest

@Service
public class WebClientService {
     public WebClientService(WebClient.Builder builder, @Value("${webclient.url}" String url) {
          this.webClient = builder.baseUrl(url)...build();
     }

     public Response send() {
          return webClient.body().exchange().bodyToMono();
     }
}

@Service
public void CallingService {
      @Autowired
      private WebClientService service;

      public void call() {
           service.send();
      }
}


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyWebTest {
        @Autowired
        private CallingService calling;

        @Test
        public void test() {
             MockWebServer mockWebServer = new MockWebServer();
             System.out.println("Current mock server url: " + mockWebServer.url("/").toString()); //this is random    

             mockWebServer.enqueue(new MockResponse()....);

             //TODO how to make the mocked server url public to the WebClient?
             calling.call();
        }
}

ご覧のとおり、私は完全な現実世界の junit 統合テストを書いています。唯一の問題は、リクエストをモックに自動的に送信するために、MockWebServerURL とポートをどのように渡すかということです。WebClient

補足: 実行中の他のテストやアプリケーションに干渉しないようにするには、必ずランダム ポートが必要ですMockWebServer。したがって、ランダム ポートを使用し、それを Web クライアントに渡す方法を見つける必要があります (または、アプリケーション プロパティを動的にオーバーライドする必要があります)。


アップデート: 私は次のように考えました。これはうまくいきます。しかし、mockserverフィールドを作成する方法を知っている人はいるでしょうか?非静的?

@ContextConfiguration(initializers = RandomPortInitializer.class)
public abstract class AbstractITest {
    @ClassRule
    public static final MockWebServer mockWebServer = new MockWebServer();

    public static class RandomPortInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,
                    "webclient.url=" + mockWebServer.url("/").toString());
        }
    }
}

ベストアンサー1

DynamicPropertySourceSpring Framework 5.2.5 (Spring Boot 2.x) 以降では、非常に便利なアノテーションを使用できます。

MockWebServer正しいポートをバインドするためにこれをどのように使用するかの完全な例を次に示します。

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public abstract class AbstractIT {

    static MockWebServer mockWebServer;

    @DynamicPropertySource
    static void properties(DynamicPropertyRegistry r) throws IOException {
        r.add("some-service.url", () -> "http://localhost:" + mockWebServer.getPort());
    }

    @BeforeAll
    static void beforeAll() throws IOException {
        mockWebServer = new MockWebServer();
        mockWebServer.start();
    }

    @AfterAll
    static void afterAll() throws IOException {
        mockWebServer.shutdown();
    }
}

おすすめ記事