Min api unit & integration tests sample#26801
Conversation
|
@captainsafia please assign a reviewer |
captainsafia
left a comment
There was a problem hiding this comment.
@brunolins16 Do you want to give this a check?
| @@ -0,0 +1,135 @@ | |||
| using Microsoft.AspNetCore.Http.HttpResults; | |||
| using todo_group; | |||
There was a problem hiding this comment.
Nit: We probably want to use PascalCase naming for this namespace.
|
|
||
| namespace todo_group; | ||
|
|
||
| public static class TodoEndpointsV2 |
There was a problem hiding this comment.
What is the goal in add a V2?
There was a problem hiding this comment.
V1 and V2 follow different patterns for accessing the underlying DB context. In V1 the context is directly injected into the endpoint whereas in V2 an additional abstraction (TodoService) is used to wrap the DB context. I think this is very common to use this abstraction (e.g. Repository pattern) and adopted in many applications to make the endpoint/controllers more testable. Rather than faking the context with an In-Memory implementation, we use a mock of a service. To show this, I've used Moq for mocking the TodoService in TodoMoqTests. Similarly for V1, I've used the In-Memory database approach found in TodoInMemoryTests
| @@ -6,11 +6,19 @@ | |||
| <ImplicitUsings>enable</ImplicitUsings> | |||
| <RootNamespace>todo_group</RootNamespace> | |||
There was a problem hiding this comment.
Maybe rename the csproj to TodoGroup.csproj?
There was a problem hiding this comment.
Also, we should update the namespace.
There was a problem hiding this comment.
yes, agreed. Will do. @Rick-Anderson could you please verify that this sample has no additional references in the documentation? This was an existing sample that I found and modified. I'm not sure whether it will break anything somewhere
| var createdResult = (Created<Todo>)await TodoEndpointsV1.UpdateTodo(updatedTodo, context); | ||
| var notFoundResult = (NotFound)await TodoEndpointsV1.UpdateTodo(new Todo { Id = 2, Title = "Invalid Title" }, context); |
There was a problem hiding this comment.
What do you think about splitting the tests?
There was a problem hiding this comment.
I think for documented examples and as a unit, this is ok. If I separate these out there will be three more test methods.
There was a problem hiding this comment.
3 tests would be better.
There was a problem hiding this comment.
I've added another fact just to check whether the todo is available inside the db,
TodoInMemoryTests.cs (When DbContext is injected)
[Fact]
public async Task GetTodoReturnsNotFoundIfNotExists()
{
// Arrange
await using var context = new MockDb().CreateDbContext();
// Act
var notFoundResult = (NotFound)await TodoEndpointsV1.GetTodo(404, context);
//Assert
Assert.Equal(404, notFoundResult.StatusCode);
}
TodoMoqTests.cs (When a service wrapper of the DbContext is injected)
[Fact]
public async Task GetTodoReturnsNotFoundIfNotExists()
{
// Arrange
var mock = new Mock<ITodoService>();
mock.Setup(m => m.Find(It.Is<int>(id => id == 404)))
.ReturnsAsync((Todo?)null);
// Act
var notFoundResult = (NotFound)await TodoEndpointsV2.GetTodo(404, mock.Object);
//Assert
Assert.Equal(404, notFoundResult.StatusCode);
}
| .AddEndpointFilter(async (context, next) => | ||
| { | ||
| app.Logger.LogInformation("Accessing todo endpoints"); | ||
| return await next(context); | ||
| }); |
There was a problem hiding this comment.
Are we planning showcase filters here as well?
There was a problem hiding this comment.
I think we can exclude filters here
fiyazbinhasan
left a comment
There was a problem hiding this comment.
@brunolins16 could you please review my comments
|
|
||
| namespace todo_group; | ||
|
|
||
| public static class TodoEndpointsV2 |
There was a problem hiding this comment.
V1 and V2 follow different patterns for accessing the underlying DB context. In V1 the context is directly injected into the endpoint whereas in V2 an additional abstraction (TodoService) is used to wrap the DB context. I think this is very common to use this abstraction (e.g. Repository pattern) and adopted in many applications to make the endpoint/controllers more testable. Rather than faking the context with an In-Memory implementation, we use a mock of a service. To show this, I've used Moq for mocking the TodoService in TodoMoqTests. Similarly for V1, I've used the In-Memory database approach found in TodoInMemoryTests
| @@ -6,11 +6,19 @@ | |||
| <ImplicitUsings>enable</ImplicitUsings> | |||
| <RootNamespace>todo_group</RootNamespace> | |||
There was a problem hiding this comment.
yes, agreed. Will do. @Rick-Anderson could you please verify that this sample has no additional references in the documentation? This was an existing sample that I found and modified. I'm not sure whether it will break anything somewhere
| .AddEndpointFilter(async (context, next) => | ||
| { | ||
| app.Logger.LogInformation("Accessing todo endpoints"); | ||
| return await next(context); | ||
| }); |
There was a problem hiding this comment.
I think we can exclude filters here
| var createdResult = (Created<Todo>)await TodoEndpointsV1.UpdateTodo(updatedTodo, context); | ||
| var notFoundResult = (NotFound)await TodoEndpointsV1.UpdateTodo(new Todo { Id = 2, Title = "Invalid Title" }, context); |
There was a problem hiding this comment.
I think for documented examples and as a unit, this is ok. If I separate these out there will be three more test methods.
…ntegrationTests/TodoIntegrationTestsV1.cs Co-authored-by: Bruno Oliveira <brunolins16@users.noreply.github.com>
…ntegrationTests/TodoIntegrationTestsV2.cs Co-authored-by: Bruno Oliveira <brunolins16@users.noreply.github.com>
| <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.7" /> | ||
| <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> | ||
| <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0-preview.7.22376.6" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0-preview.7.22376.2"> |
There was a problem hiding this comment.
Can you update and test with V 7 RC1?
There was a problem hiding this comment.
sure, will do
There was a problem hiding this comment.
packages are updated to RC1. Please check WebMinRouteGroup.csproj as the project namespace has been updated
|
@fiyazbinhasan see gitignore |
|
@brunolins16 this looks good so I'm going to merge once the .sln file is pushed - unless you have any changes needed. |
@Rick-Anderson moved both projects under |
|
Nice work @fiyazbinhasan |

contributes to #26352
@Rick-Anderson In my opinion, this could make a stand-alone comprehensive doc about writing unit and integration tests for minimal API apps. Please take a look at the sample. I've modified the existing
todo-groupsample to support the test cases. The sample could also be used to showcase the MapGroup,https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-preview-4/#route-groups