如何通过生成器配置Moq

本文关键字:配置 Moq 何通过 | 更新日期: 2023-09-27 17:59:45

我正在尝试Moq和构建器模式来设置测试CRM插件的服务。在构建器上,我有一个ConfigureMock<T>(Expression<Action<Mock<T>>>)来注入各个配置。我的问题是,一旦服务是.Setup(),我想通过.Callback<Entity>()获得服务工作的实体,但我不能在测试中将其分配给局部变量,因为我不能在回调表达式中进行分配。

这是配置:

private readonly Dictionary<Type, object> MockServices = new Dictionary<Type, object>();
public PluginContextBuilder ConfigMock<T>(Expression<Action<Mock<T>>> setupConfig) where T : class
{
    object svc = null;
    if (MockServices.TryGetValue(typeof(T), out svc))
    {
        var mockSvc = (Mock<T>) svc;
        Action<Mock<T>> setup = setupConfig.Compile();
        setup(mockSvc);
    }
    return this;
}

下面是一个我想在测试中如何配置(但不会编译)的例子:

var createdFanClub = null;
var context = new PluginContextBuilder()
                .ConfigMock<IOrganizationService>(c => 
                    c.Setup(s => 
                            s.Create(It.IsAny<Entity>()))
                            .Returns(fanclubGuid))
                            .Callback<Entity>(a => createdFanClub = a))

如果我创建一个额外的Action<Entity>来完成任务,它是有效的,但我认为这不实用,如果我有多个实体,我需要为它们做同样多的任务:

Entity createdFanClub = null;
Action<Entity> assign = a => createdFanClub = a;
var context = new PluginContextBuilder()
                .ConfigMock<IOrganizationService>(c => 
                    c.Setup(s => 
                            s.Create(It.IsAny<Entity>()))
                            .Returns(fanclubGuid))
                            .Callback<Entity>(assign))

如何通过生成器配置Moq

不确定你想完成什么。如果目标是有一个构建器,它可以处理所有需要的mock,那么为什么不直接返回mock本身,并像通常那样配置它呢:

builder.GetMock<IOrganizationService>().Setup....

这将防止你在同一个构建器上连锁调用(正如我所看到的那样),但这不是一个大的权衡,并将简化你的设置。