-
-
Notifications
You must be signed in to change notification settings - Fork 158
Ability to serialize request bodies from IIdentifiable for integration testing #1263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What do you mean by "roundtrip integration tests"? Is that sending requests to a JSON:API server and asserting on its response, or do you mean sending requests to a JSON:API client application, which calls into a JSON:API server and processes its response?
There are many ways to write tests; what you're pointing to is just how we do it internally. And it works well for us. Alternative approaches include using
What would you consider optimal, then? And what makes this approach difficult to use? What kind of errors are you concerned about? What do the complex types you're referring to look like? It would help to include code demonstrating how you'd expect such a utility to be consumed, what benefits it provides etc. And what the utility takes as input and what output it produces exactly. Asking for "I wish there was some ability" is not very actionable, because it's unclear what you expect from it or how it should work. There's no simple conversion from Honestly, I don't see our team building something like that, which would take months. Our time is pretty limited, and we have a ton of work with higher priorities. It doesn't align with our goals, which is to support clients through OpenAPI. However, I'm willing to discuss and advise on how you can build your own simple mechanism that fits your needs. |
My issue is essentially that I'm a stuck in a 4.x to 5.x upgrade where I need to ensure API compatibility to the extent that is possible. Essentially what my old 4.x compatible tests was doing was prepare a fixture dbcontext and create some basic entities into it. Then I verify create, update by copying and modifying entities then using the IRequestSerializer to create request bodies POST/PATCH and then IResponseDeserializer get the actual result back as entity and then do assertions. Without carefully reproducing these tests for 5.x I will most likely run into regressions that would have been caught. Besides the work involved in mocking the payloads manually I'm afraid I will make mistakes that could hide potential regressions. The entities I have are not very deep, only a single HasOne relationship that is required, but they have geometry as attribute (geojson) via NTS which makes the payloads a bit on the large side with real data which makes me hesistant to try and make correct manual body payloads of them as anon objects. I can fully understand that complete/flexible client serialization is out of scope for JADNC. And perhaps there is no easy way to get back what I could do. But I note you do have some auto serialization testing in SerializationBenchmarkBase involving the ResponseModelAdapter but I find it rather difficult to use, as of yet I've failed to get it to produce payloads that work. |
A concrete example of one of the most simple tests I have is: var route = "/objekter";
// get entity from fixture db
var entity = _fixture.Context.DmpFrededeOmrBk.Where(o => o.Id == _objectFixture.FrededeOmrBk.Id).First();
// convert to general form (this is what we transport in and out of JSON-API instead of exposing all "subclasses")
var objekt = entity.ToObjekt();
// reset identifiers to make it look like new object
objekt.Id = 0;
objekt.ObjektId = null;
objekt.VersionId = null;
// post through integration test host, the Post method uses IRequestSerializer and IResponseDeserializer to produce and parse the body back to entity object
var result = await _fixture.Post<Objekt>(route, objekt);
Assert.Equal(HttpStatusCode.Created, result.Response.StatusCode);
return result.Body.VersionId; // used in other test that compose this test The payload that is produced by IRequestSerializer is in this case: {
"data": {
"type": "objekter",
"attributes": {
"temaattributter": {
"fred-tkode-id": 1,
"reg-nr": "0810401",
"fred-navn": null,
"aendr-kode-id": 0,
"aar-fredn": null,
"gyldig-fra": "2023-03-13T19:36:26.4131894+01:00",
"gyldig-til": null
},
"objekt-id": null,
"version-id": null,
"systid-fra": "2023-03-13T19:36:27.111+01:00",
"systid-til": null,
"oprettet": "2023-03-13T19:36:27.111+01:00",
"oprindkode-id": 8,
"statuskode-id": 3,
"off-kode-id": 1,
"cvr-kode-id": 20228806,
"bruger-id": "123e4567-e89b-12d3-a456-426652340000",
"link": null,
"shape": {
"type": "MultiPolygon",
"coordinates": [
[
[
[488884.0, 6114493.0],
[488884.0, 6114393.0],
[488984.0, 6114393.0],
[488984.0, 6114493.0],
[488884.0, 6114493.0]
]
]
]
}
},
"relationships": {
"temakode": { "data": { "type": "temakoder", "id": "2140" } },
"vedhaeftede-filer": { "data": [] }
}
}
} So in this case not overly complex but I have a fair amount of tests with this being a very basic one.. and the devil is in the details on what exactly these tests excerise. |
The common denominator of 4.x and 5.x are the input/output bodies as strings. So to ensure you'll observe all changes during upgrade:
That does the opposite of what you need. The benchmarks serialize request bodies and deserialize response bodies. What you need instead, is something that deserializes request bodies and serializes response bodies. If I were to implement what you need, I'd start by re-adding the deleted files in the first commit of https://github.com/json-api-dotnet/JsonApiDotNetCore/pull/1075/commits, which is where client serialization was removed. |
@bkoelman thanks for the input. I've spent the last couple of hours taking a new stab on my own serialization logic. I based on some parts of ResponseModelAdapter and get the same payload as above so it's looking good. I could repurpose ConvertAttributes for ResponseModelAdapter more or less without changes and hacked the relationship part to work without a generic treenode and instead introspect the resource object directly. I don't think it's far fetched it could be cleaned up for reuse, but is still perhaps out of scope of the project and will likely have many limitations that you mentioned which will be difficult to document and maintain. So I will close this for now. |
Just for the record it did work out, got all tests working at this point. :) |
Awesome, great to hear you were able to wrap up something that unblocks you from upgrading! |
Some time ago generic client serialization was removed, which I used to implement roundtrip integration tests by serializing from mocked IIdentifiable objects.
It now looks like the only option to make such tests is to manually contruct request bodies fx. like at
JsonApiDotNetCore/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/ArchiveTests.cs
Lines 443 to 455 in 0d914d8
I wish there was some (limited?) ability to serialize IIdentifiable for integration test purposes.
The text was updated successfully, but these errors were encountered: