【问题标题】:MOQ - how to mock an interface that needs to be cast to another interface?MOQ - 如何模拟需要转换为另一个接口的接口?
【发布时间】:2011-03-31 01:24:35
【问题描述】:

我想要做的是为 I1 构建一个最小起订量 - 这很好......但是在我正在测试使用这个模拟的方法的过程中,我需要将它转换为 I2 以便访问一些属性不在 I1 上

Interface I1 
{ int AProperty{get;set;}}

Interface I2
{int AnotherProperty{get;set;}}

然后我有一些对象

Class O1 : I1 {}

Class O2 : O1 , I2 {}

问题是,当我有一个 I2 实现对象的实例时,我可以将它强制转换为 I1,以便访问通过该接口实现的方法。在代码中这不是问题,一切都按预期工作。

唯一的问题是在该类上编写单元测试。

这些接口还公开了一个名为 GetNewInstance 的方法,该方法返回一个已初始化的实现对象的实例,该实例强制转换为 IGetNewInstance 接口......我通常可以很好地模拟它并使其返回自身(因此我继续使用模拟对象)。

但是,当您尝试将此返回的 I2 类型的对象转换为 I1 时,会产生空引用结果 - 这是有道理的,因为实现 I2 的模拟对象不会从任何继承 I1 的对象继承。

问题是如何强制模拟对象同时从 I1 和 I2 继承?

【问题讨论】:

    标签: unit-testing inheritance interface moq


    【解决方案1】:

    按照我的理解,您想创建一个实现两个接口的模拟。有了起订量,就这么简单:

    var mock = new Mock<IFoo>(); // Creates a mock from IFoo
    mock.As<IBar>(); // Adds IBar to the mock
    mock.As<IBar>().Setup(m => m.BarMethod()).Returns(new object()); // For setups.
    

    现在,您可以像通常使用实现IFooIBar 的对象一样设置期望并使用您的模拟。

    对于您的 GetNewInstance 方法,您只需设置一个返回模拟本身的期望。

    【讨论】:

    • 顺便说一句,当您进行设置时,您必须使用 mock.AS.Setup(......)
    • 太棒了,这很好用。如果您需要进行 .Setup ,您可以在一行中完成所有操作,您不需要先自己执行 As,您可以在一行中完成所有操作。
    • 有没有办法将此设置作为非接口进行?
    • 我实际上不再使用起订量。到目前为止,手动创建模拟要简单得多——它也迫使我真正思考我在做什么。当使用像 resharper / Rider 这样的东西和像样的重构工具时,它会简单得多 - 它可以帮助人们意识到他们通常没有测试任何实质内容。
    猜你喜欢
    • 2011-11-13
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 2023-03-25
    • 2021-07-22
    • 2019-05-08
    • 2012-05-12
    • 1970-01-01
    相关资源
    最近更新 更多