如何在 xunit 中使用 Mock 传递映射实体

问题描述 投票:0回答:1

我正在尝试在 xunit 上使用 moq 创建一个单元测试,但是测试失败了,我客人是因为映射器,当调用

_sut.Create
时,如果我删除
MockBehavior.Strict
行为
_sut.Create,它会抛出异常
返回 0 而不是 1。

我该如何解决这个问题?谢谢您的想法。

_logger = new Mock<ILogger<BaseCRUDDomainService<ClientDTO, client>>>().Object;

var mockMapper = new MapperConfiguration(cfg =>
{
    cfg.AddProfile(new DomainMapper());
});
_mapper = mockMapper.CreateMapper();

var mockRepository = new Mock<IBaseCRUDRepository<client>>(MockBehavior.Strict);
//reponse create 1
var clientDTO = new ClientDTO
{
    Name = "name",
    Description = "description",
    Address = "address",
    Billing = "billing",
    CellphoneNumber = "cellphone",
    Email = "email"
};
mockRepository.Setup(r => r.Create(_mapper.Map<client>(clientDTO)))
    .Returns(1);
var _baseCRUDRepository = mockRepository.Object;
var _sut = new ClientCRUDDomainService(_logger, _mapper, _baseCRUDRepository);
var response = _sut.Create(clientDTO);

这是抛出的错误

Moq.MockException: 'IBaseCRUDRepository<client>.Create(client) invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.'

这是我要测试的方法:

public int Create(clientDTO entity)
{
    var entityDB = _mapper.Map<clientDB>(entity);
    return _baseCRUDRepository.Create(entityDB);
}

这是DTO类

public class ClientDTO
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Billing { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string CellphoneNumber { get; set; }
    public int[]? Users { get; set; }
}

这是数据库类

public partial class client
{
    public int Id { get; set; }
    public string name { get; set; } = null!;
    public string? description { get; set; }
    public string? billing { get; set; }
    public string? address { get; set; }
    public string? email { get; set; }
    public string? cellphone_number { get; set; }
}

这是映射器:

public class DomainMapper : Profile
{
    public DomainMapper() : base()
    {
        var configuration = new MapperConfiguration(cfg =>
        {
            cfg.AllowNullCollections = true;
        });

        configuration.CompileMappings();
        configuration.AssertConfigurationIsValid();

        CreateMap<ClientDTO, client>()
            .ForMember(db => db.Id, opt => opt.MapFrom(dto => dto.Id))
            .ForMember(db => db.cellphone_number, opt => opt.MapFrom(dto => dto.CellphoneNumber))
            .ReverseMap()
            .ForMember(dto => dto.Id, opt => opt.MapFrom(src => src.Id))
            .ForMember(dto => dto.CellphoneNumber, opt => opt.MapFrom(src => src.cellphone_number));
    }
}
c# automapper moq xunit
1个回答
0
投票

问题就在这里:

mockRepository.Setup(r => r.Create(_mapper.Map<client>(clientDTO)))
    .Returns(1);

此设置意味着,每次使用此

exact
参数调用 Create 方法时,都会返回 1。由于 client 是一个没有相等覆盖的类,因此它意味着具有相同引用的类。这显然不会发生,因为映射器每次都会返回新的类。

解决方案是使用内置参数指定约束

It.Is
:

mockRepository.Setup(
  r => r.Create(
    It.Is<client>(
      c => \** your condition here **\
    )
  ) 
)
.Returns(1);

或者使用 this nuget 它将 FluentAssertions 的等价性检查添加到 Moq:

mockRepository.Setup(
  r => r.Create(
    Its.EquivalentTo(
      /** your reference class here **/
    )
  ) 
)
.Returns(1);

我还强烈建议不要在测试中使用真正的映射器并模拟它,因为在此测试中您正在 ClientCRUDDomainService 中测试逻辑,而不是映射。对于映射器本身,您可以编写另一个测试,仅测试映射。在这种情况下,测试将变得微不足道:

var mockMapper = new Mock<IMapper>();
var clientDTO = new ClientDTO();
var client = new client();

mockMapper.Setup(x => x.Map<client>(clientDTO)).Returns(client);
mockRepository.Setup(r => r.Create(client)).Returns(1);
© www.soinside.com 2019 - 2024. All rights reserved.