27

I have a class which has a internal method and i want to mock the internal method . But i am unable to mock it i.e. it is not calling the mocked function but calling the original function. Is there any way to achieve this ?

Edit:Actually i am a novice to the Moq. I have many classes and methods of the classes to test using the Moq. Many classes are internal , many have internal methods, many have not-virtual methods . And can not change the signature on the methods and classes. Can anyone please let me know how to go about testing this scenario using Moq. Or else please suggest me some other testing framework which is easy to learn and easy to work with .

Shailendra
  • 297
  • 1
  • 4
  • 7

6 Answers6

70

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?

Daryn
  • 4,791
  • 4
  • 39
  • 52
  • 12
    This should be the accepted answer. It's a whole other debate as to whether mocking an internal method is _the right thing to do_, however if you've decided that's what you want to do, this is the way to achieve it. – CraigTP Mar 12 '13 at 09:49
  • 2
    `internal protected virtual` – jsgoupil May 12 '15 at 17:18
  • @hvelplund What I said was that you either need the public key or need to have it signed. http://stackoverflow.com/questions/106880/internalsvisibleto-attribute-isnt-working/107958#107958 – max Feb 03 '16 at 19:44
  • 1
    @max you only need to specify a public key when your own assembly is strongly named. That public key can be found in https://github.com/Moq/moq4/wiki/Quickstart, under Advanded Features, "Mocking internal types of another project,..." – bvgheluwe Jul 13 '16 at 09:20
31

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

andreister
  • 13,693
  • 2
  • 44
  • 45
  • This works, but can you perhaps tell us why it works? – MrLore Nov 11 '15 at 13:15
  • 2
    @MrLore it works because "_protected_ internal" means the method can be accessed by a subclass in _any_ assembly, and if you mark it "virtual" then your mocking subclass can provide a custom implementation – andreister Dec 15 '15 at 20:32
  • This answer is superior to Daryn's answer since it does not depend on a magic string that could change later. A comment can be added right to the method signature explaining it instead of being hidden in assemblyinfo.cs. – Moby Disk Jun 29 '16 at 19:17
  • In response to Moby Disk's comment: be aware that you still need to expose your internals to the testing assembly, i.e. Daryn's second assembly directive still holds (otherwise you wouldn't be able to set up the mock). – bvgheluwe Jul 13 '16 at 10:03
4

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

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34
1

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.

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • What if you develop your code test-first, in baby-steps? You will regularly need to deal with internal code one way or the other... – Thomas Weller May 05 '10 at 12:47
0

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

Sky Sanders
  • 36,396
  • 8
  • 69
  • 90
  • 7
    I strongly disagree: If you do TDD, then mocking internal stuff is a regular, everyday thing... – Thomas Weller May 05 '10 at 12:45
  • @Thomas - I understand your perspective. But you must realize that the classical strategy is defined as testing a classes behavior, typically by interface, rather than it's internal implementation as this tightly couples your tests to the internal implementation and induces inertia and breakage when refactoring. I would have to say that you are in the minority with your opinion. note: i have read a bit of your blog and know that you are quite thoughtful and TDD is dear to you - I just disagree with your disagreement. ;-) – Sky Sanders May 05 '10 at 12:53
  • 1
    @Poet: Agreed, if you do a behavior-based strategy then testing only against the public interface of course makes sense. What I meant was: There can be other strategies, which require testing internal stuff, and this is not necessarily a bad thing. - Maybe a minority thing, but not somehow erronous. It also makes perfect sense within its context... No need to discuss about that, I think... ;-). – Thomas Weller May 05 '10 at 13:09
  • 3
    Mocking internal methods makes perfect sense if you want to write a test for something in your library that is not visible to other libraries. "internal" is _not_ the same as "private". – mhvelplund Feb 03 '16 at 08:29
  • When approaching legacy code, mocking anything and everything is an essential ability. – clacke Mar 23 '16 at 11:38
  • There are many times one would want to mock internal methods. One clear example is mocking `HttpClient` by mocking the protected abstract `SendAsync()` method in the handler. – kovac Oct 18 '19 at 13:07
0

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

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34