【问题标题】:Moq a class that has an internal property and which implements an interfaceMoq 具有内部属性并实现接口的类
【发布时间】:2016-01-26 02:22:03
【问题描述】:

所以我有一个既实现接口又具有内部属性的类。我需要使用 Moq 来模拟这两种方法来测试方法。

public interface IMyObject
{
    bool myMethod (String input);
}

public class MyObject : IMyObject
{
    public bool myMethod(String input) {...}
    internal bool myProperty {get;}
}

现在,我可以使用 Moq 进行模拟。

我的方法:

var myIObjectMock = mockRepository.Create<IMyObject>();
myIObjectMock.Setup(m => m.myMehtod(It.IsAny<String>())).Returns((String input) => {...});

我的属性:

var myObjectMock = mockRepository.Create<MyObject>();
myObjectMock.SetupGet(m => m.myProperty).Returns(...);

我的问题是,我如何模拟两者?

问题的核心似乎是我在第一种情况下模拟一个接口,在第二种情况下模拟一个类。所以我看到的解决方案是通过模拟类或接口来模拟属性和方法。这意味着要么将内部属性转换为公共属性并将其作为接口的一部分,要么将方法设为虚拟。

是否有不涉及更改 MyObject 类的解决方案?

【问题讨论】:

  • 如果是internal,它可能不应该被测试。如果需要测试,它可能不应该是internal。看到这个相关的问题:stackoverflow.com/questions/25237971/…
  • private 范围可能是这样,但 internal 在程序集级别仍然可见,并且可能需要模拟以测试程序集中的其他组件。
  • @DLeh 在以下情况下我不同意这一点:1)内部/私有方法具有您需要在测试上下文中绕过的副作用,并且该功能不应公开(例如发送电子邮件或记录某些内容),或 2)当多个内部方法被连续调用时,“预测”这些方法的输入和输出的状态变得禁止。
  • @DLeh 在导致这个问题的代码中,内部位对其他程序集可见。它可能一开始就应该公开,但这是在我之前做出的选择,我正在尝试添加单元测试而不实际接触代码,除非没有其他选择。
  • @Lawtonfogle 如果是这种情况,只需在类上添加一个新的公共属性,该属性返回内部属性的值并在接口上公开它

标签: c# unit-testing moq


【解决方案1】:

第一个警告是,如果您的类定义和单元测试位于不同的程序集中,而且很可能是,您首先必须添加

[assembly: InternalsVisibleTo("<test project name>")]

到被测程序集的 AssemblyInfo.cs 文件中,以便内部属性甚至显示给单元测试程序集。

至于起订量需要两个单独的对象,您可能不需要。使用上面的示例

var mock = new Mock<MyObject>();
mock.As<IMyObject>().Setup(m => m.myMethod(It.IsAny<string>())).Returns(...);
mock.SetupGet(m => m.myProperty).Returns(...);

不幸的是,该设置将抛出 NotSupportedException,因为 myProperty 不是虚拟的,并且 Moq 不支持模拟非虚拟成员。您将不得不为该类型的功能查看不同的模拟库。

【讨论】:

    【解决方案2】:

    我认为内部属性不在接口上有点警告,因为您似乎在等待类的某些副作用来设置它,这可能会导致竞争条件。一般来说,你应该保持你的属性不可变以避免这种困难。

    您提到了解决此问题的唯一两种方法。侵入性最小的方法是使方法虚拟化。另一种选择是添加另一个字段,也没有那么冒险。我只会做这些改变之一并完成它。你唯一能做的就是尝试通过接口在这个类上混合一个扩展方法,我强烈建议避免。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      相关资源
      最近更新 更多