直接上代码
- 借助Mock来解决依赖注入的问题 mock+实际依赖(mapper)
- 直接Mock new 对象的方式
- 使用AutoFixtrue自动构造所有依赖
- 后面再写一篇集成测试
using AutoFixture;
using AutoFixture.AutoMoq;
using AutoFixture.Xunit2;
using GenFu;
using Microsoft.Extensions.Logging;
using Moq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnitTests.Common;
using Walle.Domain.Models.Sys;
using Walle.Domain.Service.Services;
using Walle.Integration.DsfAuthority.Interface;
using Xunit;
namespace UnitTests
{
public class SysDeptServiceTests
{
/// <summary>
/// 案例1: 使用Mock方式
/// </summary>
/// <param name="id"></param>
[Theory]
[InlineData(1)]
public void GetDeptConfigAsync_Id_ShouldBy_Equal(int id)
{
// arrange
var repository = CreateDbContext();
var oaDeptService = new Mock<IOaDeptProxyService>();
var logger = new Mock<ILogger<SysDeptService>>();
var service = new SysDeptService(repository.Object, oaDeptService.Object, logger.Object, AutoMap.Get());
//act
var result = service.GetDeptConfigAsync(id);
//assert
Assert.Equal(id, result.Result.Id);
}
/// <summary>
/// 案例二: 使用AutoFixtrue+Mock方式
/// 使用xunit自带给参数赋值方式 InlineData可以重复多次
/// </summary>
/// <param name="id"></param>
[Theory]
[InlineData(1)]
public void GetDeptConfigAsync_AutoDI_ShouldBy_True(int id)
{
// arrange
var deptConfig = GetFakeData().AsQueryable().First();
var fix = new Fixture();
//自动构造所有依赖
fix.Customize(new AutoMoqCustomization());
//Mock返回结果
var free = fix.Freeze<Mock<ISysDeptConfigRepository>>();
free.Setup(p => p.FindByDeptIdAsync(It.IsAny<long>())).Returns(Task.FromResult(deptConfig));
//注入实际依赖(真是依赖代替mock)
fix.Customizations.Add(new MockAutoMap());
var psn = fix.Create<SysDeptService>();
//act
var result = psn.GetDeptConfigAsync(id);
//assert
Assert.Equal(id, result.Result.Id);
}
/// <summary>
/// 使用AutoFixture自动给参数赋值 支持对象 枚举……
/// 高级篇: https://www.cnblogs.com/tylerzhou/p/11392248.html
/// </summary>
/// <param name="id"></param>
[Theory]
[AutoData]
public void GetDeptConfigAsync_AutoId_ShouldBy_True(int id)
{
// arrange
var repository = CreateDbContext();
var oaDeptService = new Mock<IOaDeptProxyService>();
var logger = new Mock<ILogger<SysDeptService>>();
var service = new SysDeptService(repository.Object, oaDeptService.Object, logger.Object, AutoMap.Get());
//act
var result = service.GetDeptConfigAsync(id);
//assert
Assert.True(result.Result.Id > 0);
}
#region private method
/// <summary>
/// 获取ISysDeptConfigRepository的Mock
/// </summary>
/// <returns></returns>
private Mock<ISysDeptConfigRepository> CreateDbContext()
{
var context = new Mock<ISysDeptConfigRepository>();
var deptConfig = GetFakeData().AsQueryable().First();
context.Setup(p => p.FindByDeptIdAsync(It.IsAny<long>())).Returns(Task.FromResult(deptConfig));
return context;
}
/// <summary>
/// 通过Genfu自动生成测试数据
/// </summary>
/// <returns></returns>
private IEnumerable<SysDeptConfig> GetFakeData()
{
var i = 1;
var sysDeptConfig = A.ListOf<SysDeptConfig>(26);
sysDeptConfig.ForEach(x => x.Id = i++);
return sysDeptConfig.Select(_ => _);
}
#endregion
}
}
using AutoFixture.Kernel;
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Walle.Domain.Service.MapperProfiles;
using Walle.Domain.Service.Services;
namespace UnitTests.Common
{
/// <summary>
/// 方式一、替换掉Mock使用
/// </summary>
public static class AutoMap
{
public static IMapper Get()
{
var services = new ServiceCollection();
services.AddAutoMapper(typeof(DomainMapperProfiles));
var scope = services.BuildServiceProvider().CreateScope();
IMapper _mapper = scope.ServiceProvider.GetService<IMapper>();
return _mapper;
}
}
/// <summary>
/// 方式二、替换AutofixTrue的自动生成的接口
/// </summary>
public class MockAutoMap : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (!(request is ParameterInfo pi))
return new NoSpecimen();
if (pi.Member.DeclaringType != typeof(SysDeptService) ||
pi.ParameterType != typeof(IMapper) ||
pi.Name != "mapper")
return new NoSpecimen();
var services = new ServiceCollection();
services.AddAutoMapper(typeof(DomainMapperProfiles));
var scope = services.BuildServiceProvider().CreateScope();
return scope.ServiceProvider.GetService<IMapper>();
}
}
}