简体   繁体   English

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

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

So I have a class which both implements an interface and has an internal property. 所以我有一个既实现接口又具有内部属性的类。 I need to mock both of these using Moq to test a method. 我需要使用Moq来模拟这两种方法以测试方法。

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

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

Now, I can mock either using Moq. 现在,我可以使用Moq进行模拟。

myMethod: myMethod:

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

myProperty: 我的财产:

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

My question is, how do I mock both? 我的问题是,我如何同时嘲笑两者?

The core of the problem seems to be that I'm mocking an interface in the first case and a class in the second. 问题的核心似乎是我在第一种情况下模拟了一个接口,在第二种情况下模拟了一个类。 So the solution I see is to make it so you can mock the property and the method by mocking either the class or the interface. 因此,我看到的解决方案是使其实现,以便您可以通过模拟类或接口来模拟属性和方法。 This would mean either switching the internal property into a public property and put it as part of the interface or making the method virtual. 这意味着要么将内部属性转换为公共属性,然后将其作为接口的一部分,要么使该方法成为虚拟方法。

Is there a solution that does not involve changing the MyObject class? 是否有不涉及更改MyObject类的解决方案?

I think the internal property not being on the interface is a bit of a warning, because it seems like you're waiting on some side effect of the class to set it which can lead to race conditions. 我认为内部属性不在接口上有点警告,因为似乎您在等待类的某些副作用来设置它,这可能导致争用条件。 Generally speaking, you should keep your properties immutable to avoid this kind of difficulty. 一般而言,应保持属性不变,以避免此类困难。

You mentioned the only 2 ways to work around this issue sanely. 您提到了解决此问题的仅有的两种方法。 The least intrusive would be to make the method virtual. 最少的干扰是使该方法虚拟化。 The other option, to add another field, isn't really that risky either. 添加另一个字段的另一种选择也不是那么危险。 I would just make one of these changes and be done with it. 我只是做这些更改之一并完成它。 The only other thing you could do would be to try to mix in an extension method on this class via the interface, which I would strongly recommend avoiding. 您唯一能做的就是尝试通过接口在此类上混合使用扩展方法,我强烈建议您避免使用。

The first caveat is if your class definition and unit tests are in different assemblies, and they probably are, you will first have to add 第一个警告是,如果您的类定义和单元测试位于不同的程序集中,并且可能存在,则首先必须添加

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

to the AssemblyInfo.cs file of the assembly under test for the internal property to even show up to the unit test assembly. 到要测试的程序集的AssemblyInfo.cs文件中以获取内部属性,甚至可以显示到单元测试程序集。

As for needing two separate objects for Moq, you probably don't. 至于Moq需要两个单独的对象,您可能不需要。 Using your example from above 从上面使用您的示例

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

Unfortunately, that setup will throw a NotSupportedException because myProperty isn't virtual and Moq does not support mocking non-virtual members. 不幸的是,该设置将引发NotSupportedException因为myProperty不是虚拟的,并且Moq不支持模拟非虚拟成员。 You will have to look into a different mocking library for that type of functionality. 您将必须针对该类型的功能查看其他模拟库。

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

相关问题 Moq类的接口属性 - Moq an interface property of a class 如何处理实现接口并具有基类的类? - How to approach a class which implements an interface and has a base class? 类实现接口并将其作为属性公开 - Class implements interface and expose it as property 取实现接口的类 - Take class which implements interface 类属性定义为实现接口的对象 - Class property defined as an object that implements interface 从它实现的接口创建 class 的实例 - Create Instance of a class from interface which it implements 有没有办法让每个实现接口 Ae 的 class 都有一个将 Ba 实现为属性的具体类的列表? - Is there any way to make each class that implements interface Ae has a List of one of the concrete classes that implement Ba as property? 使用Unity创建实现给定接口的类的实例时如何设置给定属性 - How to set a given property when an instance of a class which implements a given interface is created using Unity 实现与另一个接口属性的IList的接口的类...如何? - Class that implements an interface with IList of another interface property…how to? 接口方法的签名包括一个class,它实现了接口本身 - Signature of interface's method includes a class, which implements the interface itself
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM