(this post is adapted from my work-in-progress open source TDD tutorial)
(Note that I use "Statement" instead of "test" and "Specification" instead of "Test Suite" in this post)
In the previous part, I discussed how a good name is a great start for writing a Statement when there's no production code to invoke. Today, I'll introduce to you another technique.
Start by filling the GIVEN-WHEN-THEN structure with the obvious
This is applicable when you come up with a GIVEN-WHEN-THEN structure for the Statement or a good name for it (GIVEN-WHEN-THEN structure can be easily derived from a good name and vice versa). Anyway, this method is about taking the GIVEN-WHEN-THEN parts and translating them almost literally into code, then add all the missing pieces that are required for the code to compile and run.
An example speaks a thousand words
Let's take a simple example of comparing two users. We assume that a user should be equal to another when it has the same name as the other one:
GIVEN a user with any name WHEN I compare it to another user with the same name THEN it should appear equal to this other user
Let's start with the translation
The first line:
GIVEN a user with any name
can be translated literally to code like this:
var user = new User(anyName);
Then the second line:
WHEN I compare it to another user with the same name
can be written as:
user.Equals(anotherUserWithTheSameName);
Great! Now the last line:
THEN it should appear equal to this other user
and its translation into the code:
Assert.True(areUsersEqual);
Ok, so we've made the translation, now let's summarize this and see what's missing to make this code compile:
[Fact] public void ShouldAppearEqualToAnotherUserWithTheSameName() { //GIVEN var user = new User(anyName); //WHEN user.Equals(anotherUserWithTheSameName); //THEN Assert.True(areUsersEqual); }
As we expected, this will not compile. Notably, our compiler might point us towards the following gaps:
- A declaration of
anyName
variable. - A declaration of
anotherUserWithTheSameName
object. - The variable
areUsersEqual
is both not declared and it does not hold the comparison result. - If this is our first Statement, we might not even have the
User
class defined at all.
The compiler created a kind of a small TODO list for us, which is nice. Note that while we don't have full compiling code, filling the gaps boils down to making a few trivial declarations and assignments:
anyName
can be declared asvar anyName = Any.String();
anotherUserWithTheSameName
can be declared asvar anotherUserWithTheSameName = new User(anyName);
areUsersEqual
can be declared and assigned this way:var areUsersEqual = user.Equals(anotherUserWithTheSameName);
- If
User
class does not exist, we can add it by simply stating:public class User {}
Putting it all together:
[Fact] public void ShouldAppearEqualToAnotherUserWithTheSameName() { //GIVEN var anyName = Any.String(); var user = new User(anyName); var anotherUserWithTheSameName = new User(anyName); //WHEN var areUsersEqual = user.Equals(anotherUserWithTheSameName); //THEN Assert.True(areUsersEqual); }
And that's it - the Statement is complete!
No comments:
Post a Comment