如何声明/验证Micronaut控制器返回的JSON正文和属性

问题描述

我是Micronaut / Java的初学者,我正在尝试为控制器设计一些测试。我在网上找不到很多示例,所以这是我的问题。 以下是带有2个@GET请求的控制器:

@Controller("/api/v1") 
public class MyController {

private final ClientNetworkList clientNetworkList;
private final ClientStatus clientStatus;

public MyController( 
    ClientNetworkList clientNetworkList,ClientStatus clientStatus
){
    this.ClientNetworkList = clientNetworkList;
    this.ClientStatus = clientStatus;
}

    @Get(uri = "/networkList",produces = MediaType.APPLICATION_JSON_STREAM)
    Flowable<NetworkListPackage> packagesNetworkList() { 
        return ClientNetworkList.fetchPackages();
    }

    @Get(uri = "/channels/{stringParm}/status/",produces = MediaType.APPLICATION_JSON_STREAM)
    Flowable<ChannelStatusPackage> packagesstatus(stringParm) { 
        return ClientStatus.fetchPackages(genesis);
    }
}

java对象POJO:

@Introspected
public class NetworkListPackage {

    private List<NetworkList> networkList = null;
    @JsonIgnore
    private Map<String,Object> additionalProperties = new HashMap<String,Object>();

    public List<NetworkList> getNetworkList() {
        return networkList;
    }

    public void setNetworkList(List<NetworkList> networkList) {
        this.networkList = networkList;
    }

    public Map<String,Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    public void setAdditionalProperty(String name,Object value) {
        this.additionalProperties.put(name,value);
    }
}

public class NetworkList {

    private String name;
    private Boolean authEnabled;
    private Map<String,Object>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getAuthEnabled() {
        return authEnabled;
    }

    public void setAuthEnabled(Boolean authEnabled) {
        this.authEnabled = authEnabled;
    }

    public Map<String,value);
    }
}

@Introspected
public class ChannelStatusPackage {

    private String chaincodeCount;
    private String txCount;
    private String latestBlock;
    private String peerCount;
    private Map<String,Object>();

    public String getChaincodeCount() {
        return chaincodeCount;
    }

    public void setChaincodeCount(String chaincodeCount) {
        this.chaincodeCount = chaincodeCount;
    }

    public String getTxCount() {
        return txCount;
    }

    public void setTxCount(String txCount) {
        this.txCount = txCount;
    }

    public String getLatestBlock() {
        return latestBlock;
    }

    public void setLatestBlock(String latestBlock) {
        this.latestBlock = latestBlock;
    }

    public String getPeerCount() {
        return peerCount;
    }

    public void setPeerCount(String peerCount) {
        this.peerCount = peerCount;
    }

    public Map<String,value);
    }
}

以及潜在的测试:

@MicronautTest 
class MyControllerTest {

    @Inject
    @Client("/")
    RxStreamingHttpClient client; 

    @Test
    public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
        //when:
        HttpRequest request = HttpRequest.GET("/api/v1/channels/{stringParam}/status/");

        Flowable<ChannelStatusPackage> channelStatusPackageStream = client.jsonStream(request,ChannelStatusPackage.class); 
        Iterable<ChannelStatusPackage> channelStatusPackages = channelStatusPackageStream.blockingIterable();

        //then:
        //How to assert the returned body compared to the POJO?
        //How to handle the parameter in the request url?


    @Test
    public void verifyNetworkListPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
        //when:
        HttpRequest request = HttpRequest.GET("/api/v1/networkList");

        Flowable<NetworkListPackage> networkListPackageStream = client.jsonStream(request,NetworkListPackage.class); 
        Iterable<NetworkListPackage> networkListPackages = networkListPackageStream.blockingIterable();

        //then:
        //How to assert the returned body and compared to the POJO?
        //How to assert the returned properties ?
    }
}

基于前面的代码,如何测试请求的返回正文和属性与POJO匹配? 通常要进行哪些测试?

非常感谢您的帮助。

解决方法

通常,基本断言从测试对象类型开始,因此这应该验证您的架构。

另一种测试方法是使用RestAssured,女巫的可读性更高。

您需要在build.gradle中导入松弛的依赖项

    testImplementation("io.rest-assured:rest-assured:4.2.+")
    testImplementation("io.rest-assured:json-schema-validator:4.2.+")

您需要测试注释处理器来启用Micronaut注射,并为BeforeEach启用junit 5。 完整的测试依赖项:

    testAnnotationProcessor("io.micronaut:micronaut-inject-java")
    testImplementation("org.junit.jupiter:junit-jupiter-api")
    testImplementation("io.micronaut.test:micronaut-test-junit5")
    testImplementation("io.rest-assured:rest-assured:4.2.+")
    testImplementation("io.rest-assured:json-schema-validator:4.2.+")

    testRuntime("org.junit.jupiter:junit-jupiter-engine")

然后,您可以像这样编写测试:

    import static io.restassured.RestAssured.given;
    import static org.hamcrest.Matchers.equalTo;
    
    import io.micronaut.http.HttpStatus;
    import io.micronaut.runtime.server.EmbeddedServer;
    import io.micronaut.test.annotation.MicronautTest;
    import io.restassured.RestAssured;
    import javax.inject.Inject;
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;

    @MicronautTest
    class MyControllerTest {
    
      @Inject
      private EmbeddedServer embeddedServer;
    
      @BeforeEach
      public void setUp() {
        RestAssured.port = embeddedServer.getPort();
      }
    
    
      @Test
      public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
    
        given()
            .when()
            .pathParam("stringParam","value")
            .get("/api/v1/channels/{stringParam}/status/")
            .then()
            .statusCode(HttpStatus.OK.getCode())
            .body(
                "chaincodeCount",equalTo("chaincodeCountValue"),"txCount",equalTo("txCountValue"),"latestBlock",equalTo("latestBlockValue"),"peerCount",equalTo("peerCountValue"),"additionalProperties.key1",equalTo("additionalPropertyValue1"),"additionalProperties.key2",equalTo("additionalPropertyValue2")
            );
    
      }
    
    
      @Test
      public void verifyNetworkListPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
    
        given()
            .when()
            .get("/api/v1/networkList")
            .then()
            .statusCode(HttpStatus.OK.getCode())
            .body(
                "networkList.name[0]",equalTo("nameValue0"),"networkList.authEnabled[0]",equalTo("authEnabledValue0"),"networkList.additionalProperties[0].key1",equalTo("additionalPropertiesValue1"),"networkList.additionalProperties[0].key2",equalTo("additionalPropertyValue2")
            );
      }
    }

这并不是您真正想要进行测试的方式,但我希望它会有所帮助。

,

所以我最终使用了“ hasItems”匹配器或/和杰克逊模式匹配器。

    import static io.restassured.RestAssured.given;
    import static org.hamcrest.Matchers.equalTo;
    
    import io.micronaut.http.HttpStatus;
    import io.micronaut.runtime.server.EmbeddedServer;
    import io.micronaut.test.annotation.MicronautTest;
    import io.restassured.RestAssured;
    import javax.inject.Inject;
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import static org.hamcrest.Matchers.hasItems;
   import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;

    @MicronautTest
    class MyControllerTest {
    
      @Inject
      private EmbeddedServer embeddedServer;
    
      @BeforeEach
      public void setUp() {
        RestAssured.port = embeddedServer.getPort();
      }
    
    
      @Test
      public void verifyChannelStatusPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
    
        given()
            .when()
            .pathParam("stringParam","value")
            .get("/api/v1/channels/{stringParam}/status/")
            .then()
            .statusCode(HttpStatus.OK.getCode())
            .body(matchesJsonSchemaInClasspath("channelsStatus.json"))
            .body("keySet()",hasItems(
                "chaincodeCount",);
    
      }
    
    
      @Test
      public void verifyNetworkListPackagesCanBeFetchedWithCompileTimeAutoGeneratedAtClient() {
    
        given()
            .when()
            .get("/api/v1/networkList")
            .then()
            .statusCode(HttpStatus.OK.getCode())
            .body(matchesJsonSchemaInClasspath("networkList.json"))
            .body("networkList.keySet()",hasItems(
                "name","authEnabled",);
      }
    }
``