How to Mock the Internal Method of a class?

一笑奈何 提交于 2019-11-27 21:14:56

Why would you want to mock an internal method?

If you find the need to mock an internal method, say to sidestep a dependency or an interaction, you perhaps should consider redesign of the class.

Inversion of Control and Dependency Injection are some possible design strategies that can reduce coupling and increase cohesion of your classes and eliminate the need to mock internal methods.

I don't believe there is a clear path to non-public mocking with Moq.

But, if you absolutely must, you can use TypeMock Isolator to mock just about anything.

Also, just so it doesn't get lost in the din: Thomas linked a good article on using the free MS Moles to mock non-public members.

Mocking the Unmockable: Using Microsoft Moles with Gallio

You can easily mock internal virtual methods by adding the following to your AssemblyInfo.cs:

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

If your assembly is strongly named, you'll need to include the public key for DynamicProxyGenAssembly2 (Thanks to comment by @bvgheluwe; source: Moq quickstart guide):

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

I don't understand why the accepted answer says you should never do it. Isn't that what you do when you use the 'Extract and Override' (local factory method) dependency injection technique outlined by Roy Osherove in Chapter 3 of The Art Of Unit Testing?

Mark the method as internal *protected* (also virtual of course)

Not with Moq.

But you can use the free Moles framework from MS to do such things. I wrote about it here: Mocking the Unmockable: Using Microsoft Moles with Gallio. (it applies not only to Gallio, but it gives a good overall impression of what you can do with Moles...). The other alternative would be Typemock...

HTH. Thomas

Unit testing should test the interface of a class. You can mock out dependencies, but implementation details of the class itself (such as private methods) should be tested as part of the whole class, not separately, and not changed for the test (otherwise you would be testing a different unit then would really be used).

If you feel it is necessary to change the method to make the class testable, refactor the class so that the difficult part becomes a dependency, or otherwise substitutable by parameter or subclassing.

If you need to test lots of code that you can't change, you should better go with MS Moles or TypeMock from the beginning.

Free mocking frameworks like Moq give you only support on interfaces and virtual methods anyway. Does not sound as if you will go far with that...

Thomas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!