【问题标题】:Mockserver fails to match expectation for received messageMockserver 无法匹配收到的消息的期望
【发布时间】:2022-01-19 10:12:08
【问题描述】:

我正在使用

<dependency>
    <groupId>org.mock-server</groupId>
    <artifactId>mockserver-netty</artifactId>
    <version>5.11.2</version>
    <scope>test</scope>
</dependency>

用于 REST API 的集成测试。我从非常基本的期望开始,一旦最少的东西通过测试,以后会进一步详细说明测试。令我惊讶的是,MockServer 一直告诉我没有收到的请求符合我的预期。

我正在使用 Java API 编写使用 MockitoPowerMock 处理静态方法的测试。 TestNG 是测试框架。

这是我的代码:

@PowerMockIgnore({"javax.xml.parsers.*", "org.apache.logging.log4j.*", "com.sun.org.apache.*", "sun.security.*", "javax.net.ssl.*"})
@PrepareForTest({K8sTarget.class, K8sApi.class})

public class DataAccessImplTest extends PowerMockTestCase {

    private static final String HTTP_METHOD_GET = "GET";

    private static final String USER_ID= "46756123123";

    private static final String USERS_PATH = "/api/v1/users/%s";

    private static final String CONTENT_TYPE_APP_JSON = "application/json";

    @Mock
    Target mockTarget;

    @Mock
    K8sClient mockK8sClient;

    private DataAccessFactory dataAccessFactory;

    private DataAccessImpl dataAccessUT;

    private MockServerClient mockServer;

    AutoCloseable closeable;

    @BeforeClass
    public void setup() {

        // ensure all connection using HTTPS will use the SSL context defined by
        // MockServer to allow dynamically generated certificates to be accepted
        HttpsURLConnection.setDefaultSSLSocketFactory(
                new KeyStoreFactory(new MockServerLogger()).sslContext().getSocketFactory());
        this.mockServer = startClientAndServer(PortFactory.findFreePort());

        this.closeable = MockitoAnnotations.openMocks(this);

        dataAccessFactory = DataAccessFactory.getInstance();
        assertNotNull(dataAccessFactory);

        PowerMockito.mockStatic(K8sApi.class);
        PowerMockito.mockStatic(K8sTarget.class);
        PowerMockito.when(K8sApi.getK8sClient()).thenReturn(mockK8sClient);
        PowerMockito.when(K8sTarget.of(Mockito.any(K8sClient.class), Mockito.any(Target.class))).thenReturn(mockTarget);
        Mockito.when(mockTarget.getName()).thenReturn("localhost");
        Mockito.when(mockTarget.getPort()).thenReturn(this.mockServer.getPort().intValue());
        
        dataAccessUT = dataAccessFactory.createDataClient();
    }

    @BeforeMethod
    public void prepareMocks() {

        Mockito.when(mockTarget.getName()).thenReturn("localhost");
        Mockito.when(mockTarget.getPort()).thenReturn(this.mockServer.getPort().intValue());
    }

    @AfterClass
    public void teardown() throws Exception {
        this.closeable.close();
        this.mockServer.stop();
    }

    @Test
    public void getUserTest_200_Ok() throws IOException {

        dataAccessUT.getUserData(USER_ID);

        mockServer.when(request()
                .withMethod(HTTP_METHOD_GET)
                .withPath(String.format(USERS_PATH, USER_ID))
        )
        .respond(
            response()
                .withStatusCode(HttpStatusCode.OK_200.code())
                .withHeader(HttpHeaderNames.CONTENT_TYPE.toString(), CONTENT_TYPE_APP_JSON)
                .withBody("some_response_body")
        );
    }
}

这些是控制台日志:

10:06:24.067 [nioEventLoopGroup-2-1] DEBUG com.commonlibrary.httpclient.common.HttpConnectionListener:28 - 0.1 HttpConnectionListener::operationComplete: connected to [localhost:58136] from [/127.0.0.1:58204]
10:06:24.285 [MockServer-EventLog0] INFO  org.mockserver.log.MockServerEventLog:108 - 58136 received request:

  {
    "method" : "GET",
    "path" : "/api/v1/users/46756123123",
    "headers" : {
      "authorization" : [ "Bearer token" ],
      "accept" : [ "application/json" ],
      "host" : [ "localhost:58136" ],
      "content-length" : [ "0" ]
    },
    "keepAlive" : true,
    "secure" : false
  }

10:06:24.350 [MockServer-EventLog0] INFO  org.mockserver.log.MockServerEventLog:108 - 58136 no expectation for:

  {
    "method" : "GET",
    "path" : "/api/v1/users/46756123123",
    "headers" : {
      "authorization" : [ "Bearer token" ],
      "accept" : [ "application/json" ],
      "host" : [ "localhost:58136" ],
      "content-length" : [ "0" ]
    },
    "keepAlive" : true,
    "secure" : false
  }

 returning response:

  {
    "statusCode" : 404,
    "reasonPhrase" : "Not Found"
  }

10:06:24.483 [MockServer-EventLog0] INFO  org.mockserver.log.MockServerEventLog:108 - 58136 stopped for port: 58136

如您所见(除非我遗漏了什么),请求应该符合预期,但事实并非如此。我尝试了几件事,但都没有成功:

  • 将请求期望降低到最低限度,只需调用 request() 而不定义任何其他内容。这应该匹配每个传入的请求。结果相同。
  • 在期望中引入 Times.exactly(1)。结果相同。
  • 指定我在请求中发送的标头,尽管我的理解是如果它们没有在期望中设置,它们不会用于匹配。结果相同。

2 天后,我的想法已经用完了,因此我们将不胜感激任何帮助或提示。谢谢!

【问题讨论】:

    标签: java mockito integration-testing powermockito mockserver


    【解决方案1】:

    在您的测试中,您似乎在执行对被测代码的调用后在 MockServer 中创建了期望? MockServer 的控制台输出没有输出匹配/不匹配的期望(默认行为)这一事实向我表明,当向 MockServer 发出 Web 请求并且 404 是 MockServer 的默认响应时,没有设置任何期望对请求的期望。

    尝试将该期望添加为测试的第一行。

    【讨论】:

    • 谢谢!大概就是这么回事。无法确定,因为由于 Json 模式和库依赖关系与我的 pom 中的其他依赖关系后来出现问题,我决定改用 MockWebServer。我喜欢 MockServer 的脚本风格,所以一旦我再试一次,我就会回来写更新。
    猜你喜欢
    • 2020-10-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多