用Moq模拟内部类以进行单元测试 [英] Mocking internal classes with Moq for unit testing

查看:173
本文介绍了用Moq模拟内部类以进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个"ClassA"类,它对"ClassB"类有依赖性(注入到ClassA的构造函数中).我想模拟ClassB,以便可以单独测试ClassA.这两个类都是内部的.

Say I have a class "ClassA", which has a dependency on a class "ClassB" (injected into the constructor of ClassA). I want to mock ClassB so that I can test ClassA in isolation. Both classes are internal.

如果我错了,请更正我,但是Moq看起来只能模拟一个类,如果它是公共的,它具有公共的无参数构造函数,并且要模拟的方法是public virtual.我真的不想让这些类公开可见. Moq我是否想念某些东西,还是不适合我想做的事?

Correct me if I'm wrong but it looks like Moq can only mock a class if it is public, it has a public parameterless constructor, and the methods to be mocked are public virtual. I don't really want to make these classes publicly visible. Am I missing something with Moq, or is it just not suitable for what I want to do?

我想我可以创建一个由ClassB实现的接口(例如"IClassB"),将其注入到ClassA中,然后模拟该接口. ClassB仍然可以是内部的(尽管我知道接口方法必须是公共的).虽然这行得通,但我对创建许多接口感到不安,这些接口的唯一目的是支持单元测试模拟.有想法吗?

I guess I could create an interface (say "IClassB") that ClassB implements, inject that into ClassA, and mock the interface instead. ClassB can still be internal (although I realise the interface methods would have to be public). While this would work, I feel uneasy about creating lots of interfaces, whose only purpose is to support unit test mocking. Thoughts?

推荐答案

您可以通过添加

You could make internals visible to Moq by adding InternalsVisibleToAttribute in your project's assembly.cs, like this:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

为什么"DynamicProxyGenAssembly2"而不是"Moq"?这是创建的动态程序集的名称,它包含动态生成的代理类型(所有这些都由Moq使用的另一个库 Castle的DynamicProxy 处理).因此,您将类型公开给动态代理程序集,而不是Moq本身.

Why "DynamicProxyGenAssembly2" and not "Moq"? It's the name of dynamic assembly created to contain dynamically generated proxy types (all of this is handled by yet another library, Castle's DynamicProxy) which is used by Moq. So you expose types to dynamic proxy assembly, not to Moq itself.

但是,如果没有可重写的成员,那么模拟类又有什么意义呢?您不会嘲笑任何东西,所有调用都将使用实际的实现.您的第二个解决方案,

But, what's the point of mocking class if there's no overridable member? You won't mock anything and all calls will use actual implementation. Your second solution,

我想我可以创建一个由ClassB实现的接口(例如"IClassB"),将其注入到ClassA中,然后模拟该接口.

I guess I could create an interface (say "IClassB") that ClassB implements, inject that into ClassA, and mock the interface instead.

通常是我要做的.它的目的远不只是支持单元测试模拟" -它可以帮助您构建丢失的耦合组件,这始终是值得的.

is what I would normally do. Its purpose is much more than "to support unit test mocking" - it helps you build losely coupled components, which is always something worth aiming for.

这篇关于用Moq模拟内部类以进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆