简体   繁体   English

向UnityAutoMoqContainer注册通用接口

[英]Register Generic Interfaces with UnityAutoMoqContainer

We use UnityAutoMoq for mocking most of our interfaces in our unit tests, but I've recently run into a situation where we want to use a test framework to more completely simulate the actual behavior (call it an integration test if that helps you accept what I'm doing). 我们使用UnityAutoMoq来模拟单元测试中的大多数接口,但是最近我遇到了一种情况,我们希望使用测试框架来更完全地模拟实际行为(如果可以帮助您接受什么,则称为集成测试)我正在做)。

I expected UnityAutoMoq to let me register concrete mappings instead of allowing the UnityAutoMoqContainer to defer to mocking the interface. 我希望UnityAutoMoq允许我注册具体的映射,而不是允许UnityAutoMoqContainer推迟模拟接口。 This holds true to everything I've tried except for generic interfaces. 这适用于我尝试过的除通用接口之外的所有内容。 In case you're visual like me, here's a snippet of what I'm trying: 如果您像我一样视觉,这是我正在尝试的片段:

public static void Register(IUnityContainer container)
{
    ...
    container.RegisterType(typeof(IService<>), typeof(TestFrameworkService<>),
        new HierarchicalLifetimeManager(), new InjectionFactory(Create));
    ...
}

private static object Create(IUnityContainer container, Type type, string name)
{
    var T = type.GetGenericArguments().Single();
    return new TestFrameworkService<T>();// For simplicity, pretend this works
}

As you can see from above, I'm registering the generic interface to a generic concrete, then depending upon the injection factory to resolve it using the incoming type (the actual implementation was omitted for simplicity). 从上面可以看到,我正在将通用接口注册到通用混凝土,然后根据注入工厂使用传入类型来解析它(为简单起见,省略了实际实现)。 This works with a normal UnityContainer, returning the expected concrete. 这适用于普通的UnityContainer,返回预期的混凝土。 The UnityAutoMoqContainer returns a mock instead, bypassing the injection factory completely. UnityAutoMoqContainer会返回一个模拟,而不是完全绕过注入工厂。

Has anyone tried anything like what I'm trying to accomplish? 有没有人尝试过我想要完成的事情? Any ideas? 有任何想法吗?

I found that the problem lies in the underlying BuilderStrategy. 我发现问题出在底层的BuilderStrategy中。 Here's a snippet from UnityAutoMoqBuilderStrategy. 这是UnityAutoMoqBuilderStrategy的片段。

public override void PreBuildUp(IBuilderContext context)
{
    var type = context.OriginalBuildKey.Type;

    if (autoMoqContainer.Registrations.Any(r => r.RegisteredType == type))
            return;

    if (type.IsInterface || type.IsAbstract)
    {
        context.Existing = GetOrCreateMock(type);
        context.BuildComplete = true;
    }
}

Bottom line is that the builder strategy sees that the interface isn't registered and intercepts its creation. 最重要的是,构建器策略会看到未注册接口并拦截其创建。 This is because generic type definitions aren't equal to the generic types, themselves. 这是因为通用类型定义本身并不等于通用类型。

I looked into AutoMoq, which was far more recently updated, but it suffers from the same interception limitation that prevents the injection factory from firing. 我查看了最近更新的AutoMoq,但它受到相同的拦截限制,导致注射工厂无法启动。

For reference, here are the automocking libraries that I researched: 供参考,这是我研究的自动模拟库:

If someone has a recommendation, then please let me know, otherwise I'll consider this the answer. 如果有人提出建议,请让我知道,否则我会认为这是答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM