I noticed some duplicate code in a codebase I am working on that appended a filename to a directory path, so I decided to refactor it into its own method. The application I am working on is not well tested, however; I just set up the first unit tests on it two days ago, so I am very concerned to get as much code under test as possible whenever I touch it.
So I began to write a unit test like this (pseudocode):
Directory directory("a")
Expect(directory.prependPathToFilename("b")).toBeEqualTo("a/b")
However, I then remembered that the application is cross-platform. So I thought about this:
Directory directory("a")
String separator = "/" if (platform is *nix) else "\"
Expect(directory.prependPathToFilename("b")).toBeEqualTo("a" + separator + "b")
But I remembered that Roy Osherove says in section 7.1.2 ("Avoiding logic in tests") of The Art of Unit Testing (178):
If you have any of the following inside a test meethod, your test contains logic that should not be there:
switch
,if
, orelse
statements
foreach
,for
orwhile
loopsA test that contains logic is usually testing more than one thing at a time, which isn't recommended, becauset he test is less readable and more fragile. But test logic also adds complexity that may contain a hidden bug.
Now, it does not seem that in this case I am testing more than one thing at a time. Would this be a case of an acceptible logic block in a test? Is there a pattern for cleanly testing behaviors/results that are expected to be different on different platforms?