Java 根据swagger的架构进行验证时,RestAssured中的JSON架构异常无效
我正在使用restasured编写TestNG测试,以测试REST服务。我从Swagger页面复制了响应模式,并使用该模式验证响应。当我用模式手动验证响应时,一切正常。当我从脚本中验证相同内容时,它会记录一个异常 我的代码:Java 根据swagger的架构进行验证时,RestAssured中的JSON架构异常无效,java,json,jsonschema,rest-assured,json-schema-validator,Java,Json,Jsonschema,Rest Assured,Json Schema Validator,我正在使用restasured编写TestNG测试,以测试REST服务。我从Swagger页面复制了响应模式,并使用该模式验证响应。当我用模式手动验证响应时,一切正常。当我从脚本中验证相同内容时,它会记录一个异常 我的代码: given().headers("X-Correlation-Id",correlationId) .get(url).then().assertThat().body(matchesJsonSchemaInClasspath("OffersByDivStoreSchem
given().headers("X-Correlation-Id",correlationId)
.get(url).then().assertThat().body(matchesJsonSchemaInClasspath("OffersByDivStoreSchema.json"));
JSON模式:
[
{
"couponAmount": 0,
"couponAmt": 0,
"couponDescription": "string",
"couponNumber": "string",
"creationDate": "string",
"displayStartDate": "string",
"divNumber": "string",
"divStoreCoupon": "string",
"expirationDate": "string",
"maxSavings": 0,
"minPurchaseAmount": 0,
"minPurchaseQty": 0,
"offerType": "string",
"promoDescription": "string",
"promoType": "string",
"rewardYN": true,
"updateDate": "string"
}
]
实际答复:
[
{
"divNumber": "999-00001",
"couponNumber": "5",
"divStoreCoupon": "999-00001-5",
"displayStartDate": "2017-11-17",
"expirationDate": "2017-10-21",
"updateDate": "2017-12-02",
"creationDate": "2018-01-12",
"couponAmount": 0.36735077591857157,
"minPurchaseAmount": -2026457608,
"minPurchaseQty": -767686725,
"maxSavings": 0.14174878169207628,
"couponDescription": "This is a Test",
"offerType": "MD",
"rewardYN": true,
"promoDescription": "This is a Test",
"promoType": "This is a Test",
"couponAmt": 0.9053900149839325
},
{
"divNumber": "999-00001",
"couponNumber": "2",
"divStoreCoupon": "999-00001-2",
"displayStartDate": "2018-01-09",
"expirationDate": "2017-08-13",
"updateDate": "2017-08-11",
"creationDate": "2017-12-05",
"couponAmount": 0.21459988049947543,
"minPurchaseAmount": -905064853,
"minPurchaseQty": 1016266945,
"maxSavings": 0.6997004570836415,
"couponDescription": "This is a Test",
"offerType": "MD",
"rewardYN": true,
"promoDescription": "This is a Test",
"promoType": "This is a Test",
"couponAmt": 0.36784946303275545
}
]
我的进口产品包括:
import static io.restassured.RestAssured.expect;
import static io.restassured.RestAssured.given;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
以下是我的例外:
io.restassured.module.jsv.JsonSchemaValidationException: com.github.fge.jsonschema.core.exceptions.InvalidSchemaException: fatal: invalid JSON Schema, cannot continue
Syntax errors:
[ {
"level" : "error",
"schema" : {
"loadingURI" : "file:/C:/SOA_Scripts/spel-tests-offers/build/resources/test/OffersByDivStoreSchema.json#",
"pointer" : ""
},
"domain" : "syntax",
"message" : "JSON value is of type array, not a JSON Schema (expected an object)",
"found" : "array"
} ]
level: "fatal"
at io.restassured.module.jsv.JsonSchemaValidator.matchesSafely(JsonSchemaValidator.java:233)
at io.restassured.module.jsv.JsonSchemaValidator.matchesSafely(JsonSchemaValidator.java:75)
at org.hamcrest.TypeSafeMatcher.matches(TypeSafeMatcher.java:65)
at org.hamcrest.Matcher$matches.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at io.restassured.assertion.BodyMatcher.validate(BodyMatcher.groovy:76)
at io.restassured.assertion.BodyMatcher$validate$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141)
at io.restassured.assertion.BodyMatcherGroup$_validate_closure2.doCall(BodyMatcherGroup.groovy:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:3170)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:3140)
at org.codehaus.groovy.runtime.dgm$66.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:274)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at io.restassured.assertion.BodyMatcherGroup.validate(BodyMatcherGroup.groovy:47)
at io.restassured.assertion.BodyMatcherGroup$validate$3.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:141)
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:458)
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure$validate$1.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at io.restassured.internal.ResponseSpecificationImpl.validateResponseIfRequired(ResponseSpecificationImpl.groovy:643)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
at io.restassured.internal.ResponseSpecificationImpl.content(ResponseSpecificationImpl.groovy:94)
at io.restassured.specification.ResponseSpecification$content$0.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
at io.restassured.internal.ResponseSpecificationImpl.body(ResponseSpecificationImpl.groovy:244)
at io.restassured.internal.ValidatableResponseOptionsImpl.body(ValidatableResponseOptionsImpl.java:262)
at com.kroger.spel.services.OffersByDivStore.validateOffersForStore(OffersByDivStore.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:661)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:744)
at org.testng.TestRunner.run(TestRunner.java:602)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:380)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:375)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
at org.testng.SuiteRunner.run(SuiteRunner.java:289)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1301)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1226)
at org.testng.TestNG.runSuites(TestNG.java:1144)
at org.testng.TestNG.run(TestNG.java:1115)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:127)
Caused by: com.github.fge.jsonschema.core.exceptions.InvalidSchemaException: fatal: invalid JSON Schema, cannot continue
有人能告诉我这里出了什么问题。问题是我从swagger-ui.html页面上的模型模式复制了模式。但是,请注意,这是一种反应。实际模式是在/v2/api-docs.json页面上创建的。由于重用了太多的定义,必须对其进行一些处理,并且必须在每个端点将它们全部合并到一个模式文件中。下面是我的最终模式文档
{
"type": "array",
"items": {
"type": "object",
"properties": {
"couponAmount": {
"type": "number",
"format": "double"
},
"couponAmt": {
"type": "number",
"format": "double"
},
"couponDescription": {
"type": "string"
},
"couponNumber": {
"type": "string"
},
"creationDate": {
"type": "string"
},
"displayStartDate": {
"type": "string"
},
"divNumber": {
"type": "string"
},
"divStoreCoupon": {
"type": "string"
},
"expirationDate": {
"type": "string"
},
"maxSavings": {
"type": "number",
"format": "double"
},
"minPurchaseAmount": {
"type": "integer",
"format": "int32"
},
"minPurchaseQty": {
"type": "integer",
"format": "int32"
},
"offerType": {
"type": "string"
},
"promoDescription": {
"type": "string"
},
"promoType": {
"type": "string"
},
"rewardYN": {
"type": "boolean"
},
"updateDate": {
"type": "string"
}
}
}
}
更新模式后,同样的代码起作用。谢谢,你的推荐人帮我解决了这个问题。有什么例外吗?刚刚注意到我的帖子中没有提到。现在添加了例外:(这个错误已经被解决了,遗憾的是,答案没有提供任何解释,但也许你可以找出这个挥之不去的问题?谢谢@Nathan,我找到了原因。我使用了swagger ui中的模型模式来验证,而不是swagger的v2/api-docs.json中的实际模式。当我更改模式时,同样的代码工作了。很高兴它现在可以工作,如果如果您找到了确切的原因,您可以将您的解决方案作为答案发布并接受:)