ASP.NET Core Integration test using Moq Framework

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);
}
}
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store