如何使用私有设置器将模拟接口分配给属性以进行单元测试?
[InheritedExport(typeof(MyAbstractClass))
public abstract class MyAbstractClass
{
[Import] protected IFoo Foo { get; private set; }
}
public sealed class MyClass : MyAbstractClass
{
public void DoSomething()
{
if (Foo == null) throw new Exception();
var = Foo.GetBar();
//etc.
}
}
基本上,我使用 MEF 导出类并获取“通用”导入。当我想测试这些类时,我可以创建 IFoo 的模拟接口,但是如何使用私有设置器将其真正放入其中? MEF 以某种方式能够处理它,并且我不确定我还可以如何测试我的 DoSomething 方法。
[InheritedExport(typeof(MyAbstractClass))
public abstract class MyAbstractClass
{
[Import] protected IFoo Foo { get; private set; }
}
public sealed class MyClass : MyAbstractClass
{
public void DoSomething()
{
if (Foo == null) throw new Exception();
var = Foo.GetBar();
//etc.
}
}
Basically, I use MEF to export classes out and get "common" imports. When I want to test these classes I can create mock interfaces of IFoo, but how do I actually get it in there with the private setter? MEF somehow is able to handle it, and I'm not sure how else I can test my DoSomething method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您想保留 MEF 导入,最简单的方法是在每个属性上使用
ImportingConstructorAttribute
而不是ImportAttribute
。。
该解决方案有点糟糕,因为现在您必须让从 MyAbstractClass 扩展的所有类都使用
ImportingConstructorAttribute
并调用base()
如果您的抽象类被全部使用,特别是如果它决定添加另一个导入的属性,这可能会变得非常难看……现在您必须更改构造函数签名。我会坚持使用丑陋的反射......丑陋的单元测试比丑陋的代码更好。
If you want to preserve your MEF Imports, the easiest way to do so is to use the
ImportingConstructorAttribute
instead ofImportAttribute
s on each property.}
The solution kind of stinks because now you have to have all classes that extend from MyAbstractClass each use an
ImportingConstructorAttribute
and callbase()
. This can get quite ugly if your abstract class is used all over and especially if it decides to add another imported property... now you have to change the constructor signature.I'd stick with ugly reflection... better ugly unit tests than ugly code.
我相信您可以使用 MS Moles 框架来完成此任务:
http://research.microsoft。 com/en-us/projects/moles/
I believe you can accomplish this with the MS Moles framework:
http://research.microsoft.com/en-us/projects/moles/
我认为唯一的方法是使用反射。
I think the only way is using reflection.
MyAbstractClass
依赖于IFoo
,但您没有将其明确化。您应该添加一个构造函数以使依赖关系明确:现在您可以使用模拟轻松测试它。
所以,我会像这样重写你的类:
否则,你必须使用反射来获取私有设置器。太恶心了。
MyAbstractClass
has a dependency onIFoo
but you're not making it explicit. You should add a constructor to make the dependency explicit:Now you can easily test it using your mock.
So, I'd rewrite your class like this:
Otherwise, you have to use reflection to get at the private setter. That's disgusting.
反思是最好的方法。我喜欢在基本测试程序集中创建一个扩展方法,该方法具有有用的功能,例如访问/设置私有成员等。
另一种选择(如果可以接受将设置器设置为受保护而不是私有 - 这里可能是也可能不是这种情况,但如果您确实有一个具有类似愿望的受保护成员)将使您的测试子类化被测试的类。它感觉很脏,似乎不是一个好主意,但我想不出它为什么不好并且可以实现这里目标的实际原因。
reflection is the best way to do it. i like to create an extension method in a base test assembly with useful functions like accessing/setting private members and such.
another option (if it is acceptable to make the setter protected instead of private - which may or may not be the case here, but if you do have a protected member with a similar desire) would be have your test subclass the class under test. it feels dirty and doesn't seem like a good idea, but i can't think of a practical reason why it's bad and would accomplish the objective here.
尝试在构造函数中传递它:
并将抽象类中的“私有集”更改为“受保护集”。
Try to pass it in the constructor:
and change the "private set" in your abstract class to "protected set".