如何模拟一个类的内部方法?

时间:2010-05-05 11:13:39

标签: .net unit-testing moq

我有一个具有内部方法的类,我想模拟内部方法。但是我无法模仿它,即它不是调用模拟函数而是调用原始函数。有没有办法实现这个目标?

编辑:其实我是Moq的新手。我有许多类的类和方法来使用Moq进行测试。许多类是内部的,许多具有内部方法,许多具有非虚方法。并且无法更改方法和类的签名。任何人都可以让我知道如何使用Moq测试这个场景。或者请建议我一些易于学习和易于使用的其他测试框架。

6 个答案:

答案 0 :(得分:60)

您可以通过将以下内容添加到AssemblyInfo.cs来轻松模拟内部虚拟方法:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // namespace in Moq
[assembly: InternalsVisibleTo("YourTestClass")]

如果你的程序集名称很强,你需要包含DynamicProxyGenAssembly2 的公钥(感谢@bvgheluwe的评论;来源:Moq quickstart guide

[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

我不明白为什么接受的答案说你永远不应该这样做。当您使用Roy Osherove在Chapter 3 of The Art Of Unit Testing中概述的“提取和覆盖”(本地工厂方法)依赖注入技术时,您所做的并不是这样吗?

答案 1 :(得分:27)

将方法标记为internal *protected*(当然也是虚拟的)

答案 2 :(得分:3)

不是Moq。

但是你可以使用MS的免费Moles框架来做这些事情。我在这里写到:Mocking the Unmockable: Using Microsoft Moles with Gallio。 (它不仅适用于Gallio,而且它给你一个很好的整体印象,你可以用Moles做什么......)。 另一种选择是Typemock ......

HTH。 托马斯

答案 3 :(得分:1)

为什么要模拟内部方法?

如果您发现需要模拟内部方法,比如回避依赖或交互,您可能应该考虑重新设计类。

Inversion of ControlDependency Injection是一些可能的设计策略,可以减少耦合并提高类的内聚力,并消除模拟内部方法的需要。

我不相信有一个明确的途径可以与Moq进行非公开嘲笑。

但是,如果你绝对必须,你可以使用TypeMock Isolator嘲笑任何事情。

此外,只是因为它不会在喧嚣中迷失:托马斯链接了一篇关于使用免费的MS Moles嘲笑非公开成员的好文章。

Mocking the Unmockable: Using Microsoft Moles with Gallio

答案 4 :(得分:1)

单元测试应测试类的接口。您可以模拟出依赖关系,但是类本身的实现细节(例如私有方法)应该作为整个类的一部分进行测试,而不是单独测试,并且不会针对测试进行更改(否则您将测试不同的单元然后真的使用)。

如果您认为有必要更改方法以使类可测试,请重构该类以使困难部分成为依赖关系,或者通过参数或子类化替代。

答案 5 :(得分:0)

如果您需要测试许多无法更改的代码,最好从一开始就使用MS Moles或TypeMock。

像Moq这样的免费模拟框架无论如何都只支持接口和虚拟方法。听起来好像你不会那么远......

托马斯