【问题标题】:Mocking Autofac's "Resolve" extension method with TypeMock使用 TypeMock 模拟 Autofac 的“Resolve”扩展方法
【发布时间】:2010-05-01 13:53:11
【问题描述】:

我正在尝试模拟 Autofac 解析,例如

using System;
using Autofac;
using TypeMock.ArrangeActAssert;

class Program
{
    static void Main(string[] args)
    {
        var inst = Isolate.Fake.Instance<IContainer>();
        Isolate.Fake.StaticMethods(typeof(ResolutionExtensions), Members.ReturnNulls);
        Isolate.WhenCalled(() => inst.Resolve<IRubber>()).WillReturn(new BubbleGum());
        Console.Out.WriteLine(inst.Resolve<IRubber>());
    }
}

public interface IRubber
{}

public class BubbleGum : IRubber
{}

来自 Moq,TypeMock 的语法和异常让我很困惑。最初在 TestMethod 中运行它后,我不断收到类似于“WhenCalled 不能在没有补充行为的情况下运行”的异常。我尝试为每个人和他们的母亲定义行为,但无济于事。

然后我调试单步执行测试运行,发现 Autofac 触发了一个实际异常:IRubber 尚未注册。

所以很明显,静态 Resolve 函数没有被伪造,而且我无法让它被伪造,无论我如何连接它。

Isolate.WhenCalled(() => ResolutionExtensions.Resolve<IRubber>(null)).WillReturn(new BubbleGum());

... 从 Autofac 引发异常,抱怨 IComponentContext 不能为空。向它提供可能是伪造的 IContainer(或伪造 IComponentContext)让我回到“IRubber 未注册”错误。

【问题讨论】:

    标签: c# visual-studio-2010 mocking autofac typemock


    【解决方案1】:

    这可能是逆流而上的情况之一 - 创建一个“真实”容器所需的代码量,并注册了适当的依赖项,与 TypeMock 的配置相比更少或相似。我建议走这条路。

    除了让目标组件完全依赖 IContainer 之外,您还可以使用诸如 Func 之类的“关系类型”,Autofac 隐式支持这些类型并且更具表现力,而且易于模拟。 http://nblumhardt.com/2010/01/the-relationship-zoo/ 有更多关于这种方法的信息,http://code.google.com/p/autofac/wiki/DelegateFactories 也是如此。

    【讨论】:

    • 不过,你会如何模拟 Owned
    • 通常可以将Owned&lt;T&gt; 视为基本类型,如List&lt;T&gt;string - 在需要时使用其构造函数构造Owned&lt;T&gt; 的值,可能传递一个模拟 T 实例。希望这会有所帮助。
    • 对于 Owned 类的 lifeTime ctor 参数,只传入一个 IDisposable 的模拟就可以了吗?真正应该作为那个参数传递什么?谢谢!
    • 模拟就好了。在我创建的测试中,我经常使用 IDisposable 的存根实现,它揭示了一个 IsDisposed 属性 - 然后测试可以检查以确保拥有的实例已正确释放。
    猜你喜欢
    • 2017-10-23
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    相关资源
    最近更新 更多