4

I'm playing around with TDD and unit testing in general. All the examples I've seen return values and that seems like the easiest case. However what if my function doesn't return a value?

For example let's say I have an Actor class and I need a way to increase it's "health". I made a unit test like below and then make the Actor class to satisfy it, but is this ok and common to do? I don't see many examples using properties in the unit test. Should I be thinking differently with this kind of stuff?

    [TestMethod]
    public void IncreaseHealth_PositiveValue_PositiveHealth()
    {
        Actor a = new Actor();

        int beforeHealth = a.Health;

        a.IncreaseHealth(5);

        int afterHealth = a.Health;

        Assert.AreEqual(beforeHealth + 5, afterHealth);
    }
4
  • 3
    Yes, nothing wrong or uncommon with that. Your test is fine. Commented Oct 12, 2013 at 16:04
  • It is fine, I would suggest to use some random number instead of a constant, in order to increase coverage. Commented Oct 12, 2013 at 16:06
  • 1
    I wouldn't advise to use a Random number, a random number would potentially cause a test that sometimes passes and sometimes fails. If there are special cases you want to investigate (like int.MaxValue, int.MinValue, overflows, etc), create a separate test for those. They probably need special handling in any case, the default behavior of the runtime is seldom what you'd want. Commented Oct 12, 2013 at 16:11
  • Some other way to test methods is to expect some specific exception to be thrown (of course this applies to methods with return value as well) Commented Oct 12, 2013 at 16:38

1 Answer 1

5

This test is a good start. However, just like when testing value-returning methods, you should test border conditions on methods with side effects. In this case, you should also check that

  • Your method does not take negatives (or takes negatives, and works as expected)
  • When incrementing the health by some large value that overflows integer the result remains predictable (e.g. the health is capped at some value)
  • When decrementing the health by a value that is greater than the current health, the remaining health does not become negative (unless that is allowed)
  • When the health goes to zero, whatever other things that may be triggered should be triggered.

Although your use of a locally initialized object is fine, you could also put one on the unit test object, and initialize it in your [Setup] method.

Sign up to request clarification or add additional context in comments.

3 Comments

I did add the negative value test and in this case because the function name is Increase I didn't want anything to happen. The test failed and then I went back and added an if condition and it worked. I was having issues thinking of other situations but what you said makes perfect sense. I get the feeling there is a theme of common things to test for like overflows and such. Thanks.
The overflow one is interesting because VS won't even let that compile. So it seems like you can't even really do that kind of test with .NET anyway? I know C++ would probably work. I was passing in Int32.MaxValue + 1 but it won't compile.
@user441521 To reach an overflow you need to call IncreaseHealth twice - once with 1 or some other positive number, and then with Int32.MaxValue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.