Monday 27 June 2022

ASP.NET Core Integration test using Moq Framework

 Testing coverage is the key part of any project development and Testing coverage is not only about the unit testing instead Integration Testing is extremely important to make sure entire system is unbroken & bug free with any change or subsequent enhancement.

namespace CoreWebAPIMoqDemo.Services
{
public interface IWeatherForecastService
{
Task<WeatherForecast[]> GetWeatherForecast();
}
public record WeatherForecast(DateTime Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}
namespace CoreWebAPIMoqDemo.Services
{
public class WeatherForecastService : IWeatherForecastService
{
string[] summaries = new string[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

public async Task<WeatherForecast[]> GetWeatherForecast()
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateTime.Now.AddDays(index),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
)).ToArray();
return forecast;
}

}
}
using CoreWebAPIMoqDemo.Services;var builder = WebApplication.CreateBuilder(args);// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<IWeatherForecastService, WeatherForecastService>();
var app = builder.Build();// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();app.MapGet("/weatherforecast", async (IWeatherForecastService service) =>
{
return await service.GetWeatherForecast();
})
.WithName("GetWeatherForecast");
app.Run();public partial class Program { }
<PackageReference Include="Moq" Version="4.18.1" />
using Moq;
using CoreWebAPIMoqDemo.Services;
using System.Reflection;
namespace CoreWebAPIMoqDemo.Tests
{
internal class MockServices
{
public Mock<IWeatherForecastService> WeatherForecastServiceMock { get; init; }
public MockServices()
{
WeatherForecastServiceMock = new Mock<IWeatherForecastService>();
}
/// <summary>
/// This returns the collection of all mock service's interface type and the mock object, defined here i.e. <see cref="WeatherForecastServiceMock"/>.
/// </summary>
/// <returns></returns>
public IEnumerable<(Type, object)> GetMocks()
{
return GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Select(x =>
{
var interfaceType = x.PropertyType.GetGenericArguments()[0];
var value = x.GetValue(this) as Mock;
return (interfaceType, value.Object);
})
.ToArray();
}
}
}
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using CoreWebAPIMoqDemo.Services;
namespace CoreWebAPIMoqDemo.Tests
{
internal class TestMoqPOCApplication : WebApplicationFactory<Program>
{
private readonly MockServices _mockServices;
public TestMoqPOCApplication(MockServices mockServices)
{
_mockServices = mockServices;
}
protected override IHost CreateHost(IHostBuilder builder)
{
builder.ConfigureServices(services => {
foreach ((var interfaceType, var serviceMock) in _mockServices.GetMocks())
{
services.Remove(services.SingleOrDefault(d => d.ServiceType == interfaceType));
services.AddSingleton(typeof(IWeatherForecastService), serviceMock);
}

});
return base.CreateHost(builder);

}
}
}
using Moq;
using CoreWebAPIMoqDemo.Services;
using Newtonsoft.Json;
namespace CoreWebAPIMoqDemo.Tests
{
public class WeatherForecastTests
{
private readonly TestMoqPOCApplication _testMoqPOCApplication;
private readonly MockServices _mockServices;
public readonly HttpClient _client;

public WeatherForecastTests()
{
_mockServices = new MockServices();
//instantiating TestMoqPOCApplication
_testMoqPOCApplication = new TestMoqPOCApplication(_mockServices);
//creating client for api call
_client = _testMoqPOCApplication.CreateClient();
}
[Fact]
public async void GetWeatherForecastTest()
{
//mocking the business service's GetWeatherForecast() method to return result as below
var expResult = new WeatherForecast[]
{
new WeatherForecast(DateTime.Now, 26, "Bengaluru")
};

//mocking the business service's GetWeatherForecast()
_mockServices.WeatherForecastServiceMock.Setup(m => m.GetWeatherForecast()).ReturnsAsync(expResult);
//calling the api
var response = await _client.GetAsync("/weatherforecast");
string jsonString = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<WeatherForecast[]>(jsonString);
//testing the response
Assert.Equal(response.StatusCode, System.Net.HttpStatusCode.OK);
Assert.Equal(expResult, result);
}
}
}

No comments:

Post a Comment