Why you should use literals in your asserts
September 27th, 2020
I recently came across a unit test that looked similar to this:
[TestMethod] public void ValidUserName() { var credentials = new Credentials { Username = "aValidUsername" }; var sut = new TokenFactory(); var token = sut.CreateToken(credentials); Assert.AreEqual(credentials.Username, token.Clientname); }
The TokenFactory code creates a token based on the credentials that are passed in. If the username is valid, it should return that same username in a token. This unit test tests that requirement.
On the surface this unit tests looks fine. The code that makes this test pass could look like this:
public class TokenFactory { public Token CreateToken(Credentials credentials) { return new Token { Clientname = credentials.Username }; } }
The problem here is that we could change the code, breaking the requirement, but still have a passing test. We can do this by introducing a side-effect into the code:
public Token CreateToken(Credentials credentials) { credentials.Username = "somethingElse"; return new Token { Clientname = credentials.Username }; }
We can circumvent this problem by asserting on a literal string, instead of on a parameter of the Credentials object:
[TestMethod] public void ValidUserName() { var credentials = new Credentials { Username = "aValidUsername" }; var sut = new TokenFactory(); var token = sut.CreateToken(credentials); Assert.AreEqual("aValidUsername", token.Clientname); }
This way the test will - correctly - fail when the code is broken. I also think using literals makes the test easier to read.
Of course, the problem of having side effects messing up the code should be prevented altogether by using immutable objects, and generally avoiding side-effects. But I think it is a good idea to make your tests as robust as possible.
To sum it up: use literals in your asserts.