There seems to be three general patterns for testing the way a derived class interacts with it's base1. I don't really like any of them, for the reasons I've listed below. Has anyone had long term success with one of these (or another) methods for testing base class interaction?
- Change the access modifiers to allow
Friend
(internal
in C#) access and setInternalsVisibleTo
to include the mocking framework / unit test assembly
Changing the SUT to allow for testing is a test smell. If the method is Protected
, it's Protected
because that's the appropriate design for it (I actually have yet to see what I would call a "valid" use of Protected Friend
(protected internal
)).
- Use reflection and an extension method to create an accessible version of the method you want to mock... then mock it
This requires a lot of extra work to mock a single method, it's not completely type-safe (e.g. a rename would kill it), and (at least in VB), requires creating a Module
to put the method in to, which is a design nightmare (modules cannot go inside classes, so they need to be Friend
at the most restricted, and you generics are more complicated)!
- Use state testing instead of behavior testing.
Depending on how complex the base class is, this can require a lot more tests than a single behavior test for the same thing. Consider what would be required in state testing to match a Me.AssertWasCalled(Function(s) s.SendMessage(messageText, [to]))
where SendMessage
is a base class Protected
method.
1NOTE: This is not necessary in Moq which supports mocking protected methods via String
names of the method. As Ayende mentions in the link above, he specifically avoided any non compile-time type safe mocking in Rhino Mocks (which I think is a good thing!)
Just my humble opinion.
Generaly it is not a good idea to test interactions with base class. As you are going to test implementation details here.
If testing inherited class togehter with base class seems to be complicated then it is probably time to refactor and use aggregation instead of inheritance?