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

查看:25
本文介绍了使用 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?

推荐答案

您可以通过添加 InternalsVisibleToAttribute 在您项目的 assembly.cs 中,如下所示:

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天全站免登陆