[英]How to mock custom ValueResolver constructor parameters
I have a project in .NET Core and I'm using AutoMapper to map between my types.我在 .NET Core 中有一个项目,我正在使用 AutoMapper 在我的类型之间进行映射。 But I got into a problem, where I would like to mock the parameters of my custom value resolvers.
但是我遇到了一个问题,我想模拟我的自定义值解析器的参数。 I created dummy example to show the problem:
我创建了虚拟示例来显示问题:
Let's say, that I have a ValueResolver, that needs to have access to DB to resolve the given member:假设我有一个 ValueResolver,它需要访问 DB 来解析给定的成员:
public class NumberProfile : Profile
{
public NumberProfile()
{
CreateMap<NumberModel, NumberDto>()
.ForMember(dest => dest.Number, opt => opt.MapFrom<NumberValueResolver>());
}
}
public class NumberValueResolver : IValueResolver<NumberModel, NumberDto, int>
{
private readonly IRepository _repository;
public NumberValueResolver(IRepository repository)
{
_repository = repository;
}
public int Resolve(NumberModel source, NumberDto destination, int destMember, ResolutionContext context)
{
return _repository.GetNumber().Number + 3;
}
}
Let's imagine, there is logic in Resolve method, that needs to be tested and I want to mock the repository to able to test it.让我们想象一下,在 Resolve 方法中有逻辑,需要测试,我想模拟存储库来测试它。 This is what I tried in my tests
这是我在测试中尝试过的
var repositoryMock = new Mock<IRepository>();
repositoryMock.Setup(s => s.GetNumber()).Returns(new NumberModel { Number = 3 });
var mapper = new MapperConfiguration(mc =>
{
mc.AddProfile<NumberProfile>();
mc.ConstructServicesUsing(s => new NumberValueResolver(repositoryMock.Object));
});
var service = new Service(repositoryMock.Object, mapper.CreateMapper());
And then I call a method on service that triggers the mapping.然后我调用一个触发映射的服务方法。 This case is good, it works and the test passes.
这个案例很好,它有效并且测试通过。 The problem comes when I add another ValueResolver.
当我添加另一个 ValueResolver 时,问题就出现了。
public class NumberProfile : Profile
{
public NumberProfile()
{
CreateMap<NumberModel, NumberDto>()
.ForMember(dest => dest.Number, opt => opt.MapFrom<NumberValueResolver>())
.ForMember(dest => dest.AnotherNumber, opt => opt.MapFrom<AnotherNumberValueResolver>());
}
}
public class NumberValueResolver : IValueResolver<NumberModel, NumberDto, int>
{
private readonly IRepository _repository;
public NumberValueResolver(IRepository repository)
{
_repository = repository;
}
public int Resolve(NumberModel source, NumberDto destination, int destMember, ResolutionContext context)
{
return _repository.GetNumber().Number + 3;
}
}
public class AnotherNumberValueResolver : IValueResolver<NumberModel, NumberDto, string>
{
public int Resolve(NumberModel source, NumberDto destination, string destMember, ResolutionContext context)
{
return $"{source.Number} number(s)";
}
}
And then I thought I would just do this in my tests然后我想我会在我的测试中这样做
var repositoryMock = new Mock<IRepository>();
repositoryMock.Setup(s => s.GetNumber()).Returns(new NumberModel { Number = 3 });
var mapper = new MapperConfiguration(mc =>
{
mc.AddProfile<NumberProfile>();
mc.ConstructServicesUsing(s => new NumberValueResolver(repositoryMock.Object));
mc.ConstructServicesUsing(s => new AnotherNumberValueResolver());
});
var service = new Service(repositoryMock.Object, mapper.CreateMapper());
But then I get error:但后来我得到错误:
System.InvalidCastException : Unable to cast object of type 'AutoMapper_app.ValueResolvers.AnotherNumberValueResolver' to type 'AutoMapper_app.ValueResolvers.NumberValueResolver'.
System.InvalidCastException:无法将“AutoMapper_app.ValueResolvers.AnotherNumberValueResolver”类型的对象转换为“AutoMapper_app.ValueResolvers.NumberValueResolver”类型。
Did I misunderstand usage of ConstructServicesUsing
or ValueResolvers or is it something completely different?我误解了
ConstructServicesUsing
或 ValueResolvers 的用法还是完全不同的东西? Am I missing something super obvious?我错过了一些非常明显的东西吗? Is it maybe bad design?
这可能是糟糕的设计吗?
Had the same issue.有同样的问题。 After researching what is expected is a function delegate that returns a resolver based on the type (of expected resolver).
在研究了预期的是一个函数委托,它返回基于(预期解析器的)类型的解析器。 So something like
所以像
x.ConstructServicesUsing(t =>
{
if (t.Name.Contains("SomeObjectTypeResolver"))
return new SomeObjectTypeResolver();
// add more if statements if you have more than 2 resolvers
return new SomeOtherObjectTypeResolver();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.