繁体   English   中英

Moq具有内部属性并实现接口的类

[英]Moq a class that has an internal property and which implements an interface

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

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

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

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

myMethod:

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类的解决方案?

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

您提到了解决此问题的仅有的两种方法。 最少的干扰是使该方法虚拟化。 添加另一个字段的另一种选择也不是那么危险。 我只是做这些更改之一并完成它。 您唯一能做的就是尝试通过接口在此类上混合使用扩展方法,我强烈建议您避免使用。

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

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

到要测试的程序集的AssemblyInfo.cs文件中以获取内部属性,甚至可以显示到单元测试程序集。

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

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不支持模拟非虚拟成员。 您将必须针对该类型的功能查看其他模拟库。

暂无
暂无

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

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