The Inquisitive Coder - Davy Brion’s Blog

Thinking outside of the typical .NET box

Mocking dilemma

Posted by Davy Brion on July 20th, 2008

Suppose you have the following abstract class:

    public abstract class MyAbstractClass

    {

        public void DoSomethingInteresting()

        {

            // some stuff would go here…

            DoSomethingSpecific();

            // more stuff would go here…

        }

 

        protected abstract void DoSomethingSpecific();

    }

What do you do if you want to write tests that set expectations on the protected abstract method?

Ideally, i’d be able to do this:

        [Test]

        public void CallsProtectedAbstractMethod()

        {

            var mocks = new MockRepository();

            var myObject = mocks.DynamicMock<MyAbstractClass>();

 

            myObject.Expect(m => m.DoSomethingSpecific()); // <= compile error

 

            myObject.DoSomethingInteresting();

            myObject.VerifyAllExpectations();

        }

But as the comment points out, this causes a compiler error because the DoSomethingSpecific method is inaccessible to anything except derived classes.

So what is the best way to deal with this? For this example, i could manually create a derived class, set a flag in its DoSomethingSpecific implementation and then assert on the value of that flag. But that approach doesn’t really scale well to complexer classes. If i want to use a mocking framework for this, i have two options (that i can think of right now): i either make the abstract method public so the above code would compile, or i can make it protected internal and then allow my internal members to be visible to my Test project.

I dislike both approaches. I wholeheartedly agree with the “Public vs Published” stance, but making a method that really should only be accessible from derived classes public merely for testing purposes just doesn’t sit well at all with me. Changing the abstract method’s visibility from protected to protected internal seems to be the lesser of two evils, although i’ve always seriously disliked the internal keyword and especially extending the visibility of it through the InternalsVisibleTo keyword. This approach just screams “HACK!” to me, but in this case i can’t really think of anything better.

If anyone call tell me what the best way would be to deal with this specific scenario, please do share :)

On a sidenote: i am happy about the fact that i do seem to periodically reflect on the merit of my many ‘rules’ such as “thou shalt not expose thy privates to an even larger group than the internal circle to whom they’ve already been shown”. I’ve already mentioned that i’ve had it with rules that serve only theoretical purposes without any practical merit… there’s no reason why my own rules should be excluded from this :)

21 Responses to “Mocking dilemma”

  1. David Says:

    I generally extract a class with DoSomethingSpecific() as a public method and single class responsibility.


    public class MyNotSoAbstractClass {
    SomethingDoer doer;
    public void DoSomethingInteresting() {
    //..
    doer.DoSomethingSpecific();
    //..
    }
    }

    Can then test DoSomethingInteresting by replacing doer, and test DoSomethingSpecific directly via the SomethingDoer class.

    Is that too much of a cop out? :)

  2. Davy Brion Says:

    I wouldn’t call it a cop out :)
    It’s actually an interesting approach and one that probably offers a few more benefits in certain scenario’s, especially when the implementation of the original protected abstract method can get somewhat complex

    But if the implementation is more like a one-liner or at least something very simple (yet very important) then this approach feels a bit over-the-top to me :)

  3. David Says:

    Yes, funnily enough I deleted the part of my original comment about potential overkill :)

    Before I edited it, I was rambling on about how even when it seems over-the-top, generally when I have trouble testing something I find refactoring to avoid the problem pays off in the long run.

    More rambling on this topic here: http://tinyurl.com/6avqej :)

  4. David Says:

    (Warning: last comment contains gratuitous own-blog link. Got into the tinyurl habit from Twitter. :-\)

  5. Peter Says:

    I would drop the abstract keyword and make DoSomethingSpecific a partial method.
    Would that not solve your “issue”?

  6. Simone Busoli Says:

    I’m wondering if it’s right to test that protected method. Are you supposed to know what your class does internally? Or should you only care that the final result is what you expect?

  7. Davy Brion Says:

    @David:

    that’s a good post :)

    @Peter:

    i don’t really see how making it a partial method would solve this problem? Multiple derived classes from the abstract class should be possible, and partial methods don’t really help there as far as i know

    @Simone:
    Good point :)
    but what if the base class doesn’t really hold any state to assert on? Let’s use my Disposable class as an example (http://davybrion.com/blog/2008/06/disposing-of-the-idisposable-implementation/). What i really want to cover in a test, is that when someone calls the Dispose method, the protected abstract methods are called properly. The sole purpose of this class is to provide an easy implementation of the IDisposable pattern… to test that, your test pretty much has to know about the implementation. Now, i could write my own class that inherits from the Disposable class and i can make it set a flag when the abstract method is called and then in the test i could assert on the flag value. But then the test is still coupled to the implemention of the original code, only more indirectly.

  8. Davy Brion Says:

    Oh and David: don’t worry about gratuitous blog links… good stuff is supposed to be shared :)

  9. den Ben Says:

    I think it all depends on what you are trying to accomplish/test.

    You want to test DoSomethingSpecific()? Then isolate it in a seperate class and test that one. (cfr. David)

    You want to test a specific implementation of MyAbstractClass? Then use that one in your test (probably will end up in SlowTests ;-)) (cfr. Simone)

    You want to test if MyAbstract correctly fires the DoSomethingSpecific() method (can’t see why you would want to do that in this case but who knows…)? Then write your own flagging implementation and assert on it…

  10. Davy Brion Says:

    I agree with the first two statements… but writing a derived test class merely for the sake of storing a flag is no better than using a mocking framework IMHO. In the case of the Disposable class, you want to test that the abstract method (the one the derived class needs to implement to take care of its clean-up) is correctly fired when ’something’ happens. In this case, when the object is disposed. To me, that’s a valid test because that is the only purpose of the Disposable class and thus, should be tested no matter how straightforward the implementation is.

    This is one of those cases where each possible solution takes less than 5 minutes to implement, yet the discussion of what is the best approach could linger on for a long time ;)

  11. den Ben Says:

    I agree with the first two statements… but writing a derived test class merely for the sake of storing a flag is no better than using a mocking framework IMHO

    I agree. Neither is ‘better’ but i prefer a dumb flag implementation above altering the isolation level of DoSomethingSpecific().

    Maybe something like this would do the trick (doesn’t work, but illustrates the idea):

    var mockMethodBinding = mocks.ProtectedToPublicBinding();
    var myObject = mocks.DynamicMock(mockMethodBinding);
    myObject.Expect(m => m.DoSomethingSpecific());

    This is just a general idea…

  12. Davy Brion Says:

    Yeah that would be cool if that worked… I don’t think it can though, derived classes are not allowed to modify the visibility of inherited members, so the generated proxy type by the mocking framework wouldn’t be able to expose those members, unless there are some voodoo tricks which do make it possible :)

  13. den Ben Says:

    I remember an ancient programming language in which that was a possibility (the language starts with a D… :p)

    Ofcourse, the mocking framework could add a postfix to those methods (e.g. DoSomethingSpecific_()) but that would mean an extra ‘convention’. Maybe the the MethodBinding could provide some flags/insights into how the framework pre-/postfixes the protected methods. So you can expose that ‘convention’ into your code making it a bit clearer… for example:


    var mockMethodBinding = mocks.ProtectedToPublicBinding();
    mockMethodBinding.ProtectedMethodNames.PostFix = '_protected';
    var myObject = mocks.DynamicMock(mockMethodBinding);
    myObject.Expect(m => m.DoSomethingSpecific_protected());

  14. Davy Brion Says:

    it’s a hack… but i like this one :)

    still not sure if you could get that to work though… it changes the public interface of the type being mocked, so you have to get the compiler to recognize the modified interface as well. And since the type is generated at runtime, it’s probably gonna be hard to get the new interface to be recognized at compile time :)

  15. den Ben Says:

    Yeah… got a bit carried away there (just shows that I have no mocking xp at all…). Getting that to work would probably mean hacking even further.

    Maybe an Expect method that takes a string and an isolation level as input would be a more feasible track for this type of scenario.


    myObject.Expect("DoSomethingSpecific", MethodIsolation.Protected);

    Upside is the compiler doesn’t need to know about it at all and DoSomething can stay abstract and protected. Downside is that you’d have to work with string literals.

  16. Dew Drop - July 21, 2008 | Alvin Ashcraft's Morning Dew Says:

    [...] Mocking Dilemma (Davy Brion) [...]

  17. Tom Says:

    As an alternative to creating an inherited class to set some flags when the method is called, how about extending the abstract class ‘MyAbstractClass’ with another abstract class ‘MyAbstractTestClass’ inside the test project, and then write the actual TestFixture inside ‘MyAbstractTestClass’ as an inner class.

    By using another abstract class you don’t have to implement anything while you can still access the ‘DoSomethingSpecific()’ method, because your test is inside an inner class of ‘MyAbstractTestClass’…


    public abstract class MyAbstractTestClass : MyAbstractClass
    {
    [TestFixture]
    public class InnerTestClass
    {
    [Test]
    public void CallsProtectedAbstractMethod()
    {
    var mocks = new MockRepository();
    var myObject = mocks.DynamicMock();

    myObject.Expect(m => m.DoSomethingSpecific());

    mocks.ReplayAll();

    myObject.DoSomethingInteresting();
    myObject.VerifyAllExpectations();
    }
    }
    }

  18. Davy Brion Says:

    see Tom, this is exactly why i’ve been telling you to start blogging already! :)

    i really like this approach and it works great, thx :)

  19. The Inquisitive Coder - Davy Brion’s Blog » Blog Archive » Mocking Dilemma, Solved! Says:

    [...] Mocking dilemma [...]

  20. Reflective Perspective - Chris Alcock » The Morning Brew #141 Says:

    [...] Mocking dilemma - Davy Brion poses a question about mocking a particular abstract class and method set up - some interesting comments. [...]

  21. HardTime Says:

    Puclic or protected, I still think this is a hack… and one I’ve used myself I must admit. The original xUnit thing was derived from the idea of self-testing-classes (way back in the C days, Erich Gamma and the likes, … and SmallTalk admittedly, all the other industry-influencing people like mr. Kaye, and mr. Kent and so on ). A class would contain its own test method that would handle all the unit-testing. In order to seperate test compilation with production compilation one could either use some ugly preprocessor directive or use the ‘white box’ testing approach (mainly through inheritance). Neither option appeals to me. I don’t want to declare anything as protected just for testing purposes, when in production code it should be private. These days most of the times there’s an other way, the dependancy injection pattern solves some of these issues, but not all of them.
    Again, I must say that I have used this hack as a get out of a pickle situation more than on one occasion. A dillema indeed…

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>