C #: How do I check for methods called in a specific order?

I have the following class:

public class Script
{
    IPrinter _printer;

    public Script(IPrinter printer)
    {
        _printer = printer;
    }

    public void Print(TextWriter writer)
    {
        _printer.PrintComment(writer, "lolz");
        writer.WriteLine("omg this complicates things";
        _printer.PrintSpecial(writer);
        if (signoff)
            _printer.PrintComment(writer, "kthxbye");
    }
}

      

How do I set up my test to assert that the printer's methods are called in the correct order with the correct parameters?

I could manually create a "fake" printer and do a status test on the writer, but since the context is large (especially since the script also works with the author) I would like to avoid it.

I am using nunit and rhino mocks. Any thoughts on architectural changes or mocking procedures to make this easier to test are appreciated. Unfortunately, the real code I am working with is more complicated, but this is the gist.

+2


source to share


3 answers


You cannot use static AAA syntax to test behavior in Rhino, unfortunately you need to revert to the old "Replay" style to do this AFAIK.

I'm not a rhino expert, I usually use Moq, but I think this is correct:



var mocks = new MockRepository();
var printer = mocks.DynamicMock<IPrinter>();
using (mocks.Ordered())
{
    printer.Expect(x => x.PrintComment());
    printer.Expect(x => x.PrintSpecial());
    printer.Expect(x => x.PrintComment());
}
printer.Replay();
Script = new Script(printer);

... Execute Test...

printer.VerifyAllExpectations();

      

+5


source


You don't need to check which ordering methods are called. Testing should be done to ensure that the appropriate effects have occurred because you called the method Print

.



However, if you really need to do this, I think the best way would be to create a mock IPrinter that stores order functions and passed parameters, which can then be asserted in tests.

+3


source


You don't need to test the compiler. If you were doing any streams I could see it ... but in this case, with what you posted, you don't know.

As you said, you can create a printer layout and check that the methods are called in order, but that would be overkill.

You would probably be better off throwing exceptions in certain methods if the preconditions (i.e. the previous methods) are not called, but refer to the need for refactoring into a single method.

Alternatively, you can use the Method Template to ensure that methods are called in order, but if you don't have additional objects that need to use that order, this would be overkill.

0


source







All Articles