Add unit tests for FeedbackReceiverController.cs

This commit is contained in:
Denis-Cosmin Nutiu 2021-05-29 21:12:36 +03:00
parent 39c0bf72b8
commit 285b375550
12 changed files with 150 additions and 52 deletions

View file

@ -7,9 +7,18 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Retroactiune.WebAPI\Retroactiune.WebAPI.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using AutoFixture.Xunit2;
using Microsoft.AspNetCore.Mvc;
using Moq;
using Retroactiune.Controllers;
using Retroactiune.Models;
using Retroactiune.Services;
using Xunit;
namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
{
public class TestFeedbackReceiverController
{
[Fact]
public async Task Post_Successful_Creation_No_items()
{
var mapper = TestUtils.GetMapper();
var mockService = new Mock<IFeedbackReceiverService>();
// Test
var controller = new FeedbackReceiverController(mockService.Object, mapper, null);
var result = await controller.Post(new List<FeedbackReceiverDto>());
// Assert, null because we don't have the ApiBehaviourOptions set, which would generate the IActionResult for the invalid input.
Assert.Null(result);
}
[Theory, AutoData]
public async Task Post_Successful_Creation_Two_items(IEnumerable<FeedbackReceiverDto> items)
{
var mapper = TestUtils.GetMapper();
var mockService = new Mock<IFeedbackReceiverService>();
// Test
var controller = new FeedbackReceiverController(mockService.Object, mapper, null);
var result = await controller.Post(items);
// Assert
Assert.IsType<OkObjectResult>(result);
}
}
}

View file

@ -0,0 +1,17 @@
using AutoMapper;
namespace Retroactiune.Tests.Retroactiune.WebAPI
{
public static class TestUtils
{
public static IMapper GetMapper()
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});
var mapper = configuration.CreateMapper();
return mapper;
}
}
}

View file

@ -1,19 +0,0 @@
using NUnit.Framework;
namespace Retroactiune.Tests
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
// TODO: Test WebAPI, todo, Test service. =) :(
Assert.Pass();
}
}
}

View file

@ -0,0 +1,13 @@
using System;
using Xunit;
namespace Retroactiune.Tests
{
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}
}

View file

@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Retroactiune.Models;
using Retroactiune.Services;
@ -13,13 +16,52 @@ namespace Retroactiune.Controllers
[Route("api/v1/[controller]")]
public class FeedbackReceiverController : ControllerBase
{
private readonly FeedbackReceiverService _service;
private readonly IOptions<ApiBehaviorOptions> _apiBehaviorOptions;
private readonly IFeedbackReceiverService _service;
private readonly IMapper _mapper;
public FeedbackReceiverController(FeedbackReceiverService service, IMapper mapper)
public FeedbackReceiverController(IFeedbackReceiverService service, IMapper mapper,
IOptions<ApiBehaviorOptions> apiBehaviorOptions)
{
_service = service;
_mapper = mapper;
_apiBehaviorOptions = apiBehaviorOptions;
}
/// <summary>
/// Inserts FeedbackReceivers into the database.
/// </summary>
/// <param name="items">The list of FeedbackReceivers</param>
/// <returns>A BasicResponse indicating success.</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the items is invalid</response>
[HttpPost]
[ProducesResponseType(typeof(BasicResponse), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Post([Required] IEnumerable<FeedbackReceiverDto> items)
{
var feedbackReceiversDto = items.ToList();
if (!feedbackReceiversDto.Any())
{
ModelState.AddModelError(nameof(IEnumerable<FeedbackReceiverDto>),
"At least one FeedbackReceiver item is required.");
return _apiBehaviorOptions?.Value.InvalidModelStateResponseFactory(ControllerContext);
}
var mappedItems = feedbackReceiversDto.Select(i =>
{
var result = _mapper.Map<FeedbackReceiver>(i);
result.CreatedAt = DateTime.UtcNow;
return result;
});
await _service.CreateManyAsync(mappedItems);
return Ok(new BasicResponse()
{
Message = "Items created successfully!"
});
}
[HttpDelete("{id}")]
@ -29,25 +71,6 @@ namespace Retroactiune.Controllers
return NoContent();
}
[HttpPost]
public async Task<BasicResponse> Post(IEnumerable<FeedbackReceiverDto> items)
{
var mappedItems = items.ToList().Select(i =>
{
var result = _mapper.Map<FeedbackReceiver>(i);
result.CreatedAt = DateTime.UtcNow;
return result;
});
await _service.CreateMany(mappedItems);
return new BasicResponse()
{
Message = "Items created successfully!"
};
}
[HttpGet("{id}")]
public BasicResponse Get(long id)
{

View file

@ -1,6 +1,7 @@
using AutoMapper;
using Retroactiune.Models;
namespace Retroactiune.Models
namespace Retroactiune
{
public class MappingProfile : Profile
{

View file

@ -19,7 +19,7 @@
},
"Retroactiune": {
"commandName": "Project",
"launchBrowser": true,
"launchBrowser": false,
"launchUrl": "",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {

View file

@ -12,7 +12,7 @@ namespace Retroactiune.Services
/// Service that simplifies access to the database for managing FeedbackReceiver items.
/// <see cref="FeedbackReceiver"/>
/// </summary>
public class FeedbackReceiverService
public class FeedbackReceiverService : IFeedbackReceiverService
{
private readonly IMongoCollection<FeedbackReceiver> _collection;
private readonly ILogger<FeedbackReceiverService> _logger;
@ -25,7 +25,7 @@ namespace Retroactiune.Services
_logger = logger;
}
public async Task CreateMany(IEnumerable<FeedbackReceiver> items)
public async Task CreateManyAsync(IEnumerable<FeedbackReceiver> items)
{
try
{

View file

@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Retroactiune.Models;
namespace Retroactiune.Services
{
public interface IFeedbackReceiverService
{
public Task CreateManyAsync(IEnumerable<FeedbackReceiver> items);
}
}

View file

@ -32,7 +32,7 @@ namespace Retroactiune
// Services
services.AddSingleton<FeedbackReceiverService>();
services.AddSingleton<IFeedbackReceiverService, FeedbackReceiverService>();
// WebAPI
services.AddControllers();

View file

@ -2,7 +2,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Retroactiune.WebAPI", "Retroactiune.WebAPI\Retroactiune.WebAPI.csproj", "{A40A0DBB-42D4-4619-9B80-120517561DF1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Retroactiune.Tests", "Retroactiune.Tests\Retroactiune.Tests.csproj", "{08AE3560-A324-4843-90DB-17DFC54600B5}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Retroactiune.Tests", "Retroactiune.Tests\Retroactiune.Tests.csproj", "{2A2B5780-B8EF-4260-9EC1-3A2BFE5CDA7F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -14,9 +14,9 @@ Global
{A40A0DBB-42D4-4619-9B80-120517561DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A40A0DBB-42D4-4619-9B80-120517561DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A40A0DBB-42D4-4619-9B80-120517561DF1}.Release|Any CPU.Build.0 = Release|Any CPU
{08AE3560-A324-4843-90DB-17DFC54600B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08AE3560-A324-4843-90DB-17DFC54600B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08AE3560-A324-4843-90DB-17DFC54600B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08AE3560-A324-4843-90DB-17DFC54600B5}.Release|Any CPU.Build.0 = Release|Any CPU
{2A2B5780-B8EF-4260-9EC1-3A2BFE5CDA7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A2B5780-B8EF-4260-9EC1-3A2BFE5CDA7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A2B5780-B8EF-4260-9EC1-3A2BFE5CDA7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A2B5780-B8EF-4260-9EC1-3A2BFE5CDA7F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal