tags:

views:

21

answers:

2

Hi,

I am interested in the best way to write unit tests for a class whose public API involves some kind of a flow, for example:

public class PaginatedWriter {
public void AppendLine(string line) { ... }
public IEnumerable<string> GetPages() { ... }
public int LinesPerPage { get; private set; }
}

This class paginates text lines into the given number of lines per page. In order to test this class, we may have something like:

public void AppendLine_EmptyLine_AddsEmptyLine() { ... }
public void AppendLine_NonemptyLine_AddsLine() { ... }
public void GetPages_ReturnsPages() {
 writer.AppendLine("abc");
 writer.AppendLine("def");
 var output = writer.GetPages();
 ...
}

Now, my question is: is it OK to make calls to AppendLine() in the last test method, even though we are testing the GetPages() method?

I know one solution in such situations is to make AppendLine() virtual and override it but the problem is that AppendLine() manipulates internal state which I don't think should be the business of the unit test.

A: 

The way I see it is that tests usually follow a pattern like 'setup - operate - check - teardown'.

I concentrate most of the common setup and teardown in the respective functions.

But for test specific setup and teardown it is part of the test method.

I see nothing wrong with preparing the state of the Object Under Test using method calls of that object. In OOP I would not try to decouple the state from the operations since the paradigm goes to great lengths to unify them and if possible even hide the state. In my view the unit under test is the Class - state and methods.

I do make visual distinction in the code by separating the setup block from the operate block and the verify block with an empty line.

Peter Tillemans
Yeah, It seems that If we were to apply the "test one method only" rule strictly, we'd end up with a bunch of classes that have procedural interfaces.
Mohammad
A: 

Yes, I'd say that's absolutely fine.

Test in whatever way you find practical. I find there's rather too much dogma around testing exactly one thing in each test method. That's a lovely ideal, but sometimes it's just not nearly as practical as slightly less pure alternatives.

Jon Skeet