Kostya Sydoruk
Kostya Sydoruk

Reputation: 144

Rhino mocks how to check if a method was called by another method from the same class

I ran into a bit of a trouble while testing one of my classes. I have an abstract class which contains one public method and two protected abstract once. I need to test weather public method calls one of the abstract once.

Heres an example of how my code looks like:

public abstract class A
{
    public string DoSomething(stirng input)
    {
        var output = new StringBuilder();

        foreach (var currentChar in input)
        {
            output.Append(DoSomethingElse(currentChar));
        }

        return output.ToString();
    }

    protected abstract char DoSomethingElse(char charToChange);
}

public class B : A
{
    protected override char DoSomethingElse(char charToChange)
    {
        var changedChar = charToChange;
        // Some logic changing charToChange's value
        return changedChar;
    }
}

Because DoSomethingElse() is protected I've created a class that publishes that method

public class BPublisher : B
{
    public virtual new char DoSomethingElse()
    {
        return base.DoSomethingElse()
    }
}

My question is how do I test the fact that DoSomething() called DoSomethingElse() using Rhino mocks?

P.S. I have tried using Expect and AssertWasCalled but without success.

Upvotes: 1

Views: 1272

Answers (2)

Stefan Steinegger
Stefan Steinegger

Reputation: 64628

When you declare another method using new, it doesn't have anything to do with your original protected method. Because it is not virtual, you can not mock it. Making it virtual and mock that is kind of weird, because you derive a test class to create a mock from.

I would actually not try to use a mock in this case. Why not return a useful result in a property?

public class BPublisher : B
{
    public readonly StringBuilder chars = new StringBuilder();

    public virtual new char DoSomethingElse(char charToChange)
    {
        chars.Append(charToChange);
        return charToChange;
    }
}

var a = new BPublisher();
a.DoSomething("abc");
Assert.AreEqual("abc", a.chars.ToString());

At the end it is still weird. It's sometimes hard to test abstract base classes. You may also consider to make DoSomethingElse public.

Upvotes: 1

Brian Agnew
Brian Agnew

Reputation: 272257

Do you really need to test this ? Unit testing should test the output based on a set of inputs. How you implement this is of no concern to the test (in output you could include the resultant members/state of the object)

e.g. if I refactor your class heavily, I still want the tests to pass. e.g. if I give you an input do I still get the output. I don't really want the tests to fail if the implementation differs (since I don't really care about the implementation)

Upvotes: 2

Related Questions