Skip to content

RFC: Fluent Testing API #294

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

Closed
jaredcnance opened this issue Jun 10, 2018 · 3 comments
Closed

RFC: Fluent Testing API #294

jaredcnance opened this issue Jun 10, 2018 · 3 comments
Labels
enhancement help wanted RFC Request for comments. These issues have major impact on the direction of the library.

Comments

@jaredcnance
Copy link
Contributor

jaredcnance commented Jun 10, 2018

Update: I am considering moving this as an add-on to DotnetTestAbstractions.

This is part of the initiative defined by #251.

Status: WIP (feedback desired)

Summary

Provide a fluent testing API that abstracts away the boilerplate required by most json:api requests.

Motivation

Currently, there is a lot of boilerplate required to test a single json:api endpoint. For example, this is one of the tests used against the example app in this repo:

// arrange
var builder = new WebHostBuilder()
.UseStartup<Startup>();
var httpMethod = new HttpMethod("POST");
var server = new TestServer(builder);
var client = server.CreateClient();
var context = _fixture.GetService<AppDbContext>();
var owner = new JsonApiDotNetCoreExample.Models.Person();
context.People.Add(owner);
await context.SaveChangesAsync();
var route = "/api/v1/todo-collections";
var request = new HttpRequestMessage(httpMethod, route);
var content = new
{
data = new
{
type = "todo-collections",
relationships = new
{
owner = new
{
data = new
{
type = "people",
id = owner.Id.ToString()
}
}
}
}
};
request.Content = new StringContent(JsonConvert.SerializeObject(content));
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
// act
var response = await client.SendAsync(request);
// assert
Assert.Equal(HttpStatusCode.Created, response.StatusCode);

We should be able to drastically reduce this to something a bit more readable:

// arrange
var expectedOwner = new Person();
var expectedTodoCollection = new TodoCollection();
var request = new CreateRequest<TodoCollection>(expectedTodoCollection)
   // need to add `expectedOwner` to db prior to sending the request
  .WithNewRelationship(todoCollection => todoCollection.Owner, expectedOwner);

// act
var resultantTodoCollection = await request.SendAndValidateAsync();
/* your assertions go here */

Detailed Design

Create a new package JsonApiDotNetCore.Testing

Possible APIs

API Description
JsonApiRequest<T>.SendAndValidateAsync() Sends the request and performs json:api related validations
JsonApiRequest<T>.SendAsync() Sends the request without performing validations
JsonApiRequest<T>.Dump() Writes the HTTP request to the console
CreateRequest<T> RequestBuilder for POST requests
GetRequest<T> RequestBuilder for GET requests
UpdateRequest<T> RequestBuilder for PATCH requests
DeleteRequest<T> RequestBuilder for DELETE requests
BulkRequest RequestBuilder for operations request
IWriteRequest<T>.WithNewRelationship This would create the entity prior to sending the request and then include the rio in the relationships.{}.data element
IRequest<T>.WithHeader Add custom headers
IGetRequest<T>.Filter Add filter
IGetRequest<T>.Sort Add filter
IGetRequest<T>.Sort Add filter
IGetRequest<T>.Include Include relationship
IGetRequest<T>.Page Paginate the request
... ...

Considerations

  • How to provide value and remain ORM agnostic (e.g. WithNewRelationship needs to be able to create the entity prior to sending the request)
  • Can we build transactional testing in by default?
  • We need to be very careful around error handling. If an error occurs, we need to communicate the source of the error and what should be done to remedy it (to the best of our ability) back to the developer.
@jaredcnance jaredcnance added the RFC Request for comments. These issues have major impact on the direction of the library. label Jun 10, 2018
@maurei
Copy link
Member

maurei commented Oct 15, 2018

Idea regarding JsonApiRequest<T>.SendAsync: make such functionality available in the core package.

Relates to #253 where wayne-o mentions something similar.

Use case: currently have a microservice and a JADNC API. The microservice

  • consumes both some 3rd party API and my JADNC API (GET)
  • does some business logic with the 3rd party data, and eventually does some POSTs to the JADNC API

The microservice currently also includes the JsonApiDotNetCore package to use it as a JA client. More specifically, it requires the deserializer for fetching data and the serializer for sending data. For this I currently need to build the ContextGraph in startup.cs as usual, but I also needed

Some ideas on how to move forward with this:

  • Allow for better reusability of the (de)serializers outside of the context of JADNC services such that this can be implemented more easily w/o having to dig into the package (i.e. figuring out that one needs to do the above two fixes to get serialization to work, and maybe even w/o having to build the context graph?). Appeals to the idea of more separation of concerns as in RFC: Separate Concerns of JsonApiContext #253
  • Support JsonApiRequest<T>.SendAsync out of the box so that no manual usage of the (de)serializers is needed

@jaredcnance
Copy link
Contributor Author

jaredcnance commented Oct 26, 2018

@maurei thanks for the feedback (as always)! I'm in agreement that having a client library that can use the ResourceGraph and serialization APIs would be very beneficial. I think it is separate from this issue (although this issue will become dependent upon completion of the client APIs). When I have some time I'll put together a proposal in a separate issue.

@bart-degreed
Copy link
Contributor

I'm closing this, because in the mean time we've done major refactorings on the test infrastructure code, resulting in our integration tests to no longer contain a lot of boilerplate code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement help wanted RFC Request for comments. These issues have major impact on the direction of the library.
Development

No branches or pull requests

3 participants