Ilya Chernomordik
Ilya Chernomordik

Reputation: 30205

Is it a good idea to use same constants in unit test that are used in system under test?

Imagine the following method:

GetEntity => new { Name = Constants.EntityName };

Now I would have a unit test to check that my code returns a correct entity:

var result = GetEntity();
Assert.Equal(Constants.EntityName, result.Name);

Or

var result = GetEntity();
Assert.Equal("ConstantEntityNameValue", result.Name);

Now the question is if it a good idea to use the same constant in the unit test? If one makes an error in the constant, then it will affect the unit test as well and it will pass though there is an error, but then we'll have to duplicate the string in possibly many unit tests.

I am wondering if it's worth to hardcode all the values or it is good enough to use constants.

P.S. These are useless bare bone examples just to illustrate the idea

Upvotes: 5

Views: 1092

Answers (1)

Dirk Herrmann
Dirk Herrmann

Reputation: 5939

Ask yourself the following question: How would you document your function for a user?

A) Assume your documentation goes in the following direction:

"GetEntity will create a new entity with default content. Name will be given the content of Constants.EntityName, which means, later in the code you can check if Name has still its default value by comparing it against Constants.EntityName."

As you see, in this documentation the user is not informed about the actual value of Constants.EntityName. The actual value is irrelevant. In this case, I would recommend to also compare against Constants.EntityName in your tests. Reason: The actual value is not of importance, and client code should not care about the actual value.

B) Assume in contrast you would document your function as follows:

"GetEntity will create a new entity with default content. Name will be given the content of Constants.EntityName, which is 'ConstantEntityNameValue'. [...]".

In this case, I recommend to have at least two test cases: One testing that the Name attribute equals Constants.EntityName, and a second test to verify that Constants.EntityName equals 'ConstantEntityNameValue'. Reason: The literal is part of the specification, so client code might use it. There is a distinction in the documentation, however, what the function is documented to do (create the object using Constants.EntityName) and what the value of the constant is.

C) Finally assume your function is documented as follows:

"GetEntity will create a new entity with default content. Name will be given the value 'ConstantEntityNameValue'. [...]".

In this case, you should compare against the literal 'ConstantEntityNameValue' in your test. Reason: Client code will be written that uses this literal for comparisons, so you should ensure by your test that the function actually uses this literal also for future releases.

Upvotes: 3

Related Questions