Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing and assert case for void method

I'm trying to create some unit testing for a void method. Basically the method is intended to show the role of a system user and implement it within the software.

This is the method:

public void setPersonObj(Person typeObj)
{
    this.typeObj = typeObj;
    createMain();
}

How would I create an assert case in a separate class that uses unit testing to check this method?

Many thanks

like image 439
user1060187 Avatar asked Nov 22 '11 16:11

user1060187


People also ask

Can I unit test a void method?

In conclusion, there are multiple ways to test the void method, which is dependent on the method's side-effects and what kind of test you wish to run. A unit test checks the method's functionality and can cover the void method if the side effect is stored in publicly available property.

What to assert in a void method?

Whenever we write unit test cases for any method we expect a return value from the method and generally use assert for checking if the functions return the value that we expect it to return, but in the case of void methods, they do not return any value.


2 Answers

If the method is void it clearly has some side-effects. Otherwise it would be a no-op. So you have no choice and need to validate these side-effects.

How to test these side effects is dependant on technology you use and testing approach:

  • if the method calls some other collaborators/objects, mock them and verify mocks afterwards

  • if it changes the state of some other components (adding element to collection, modifying field) query and assert them

  • if it stores something on the disk/database, query them as well

  • if it display some window in Swing, you need to use Swing testing frameworks like Window Licker

  • if... you could provide some more technical details?

BTW A setter that performs some extra unrelated logic is a code smell. People maintaining such code will find it really hard to figure out that this innocent setPersonObj() does something except... setting.

Also all these names: Person, PersonObj and typeObj should be the same for consistency and compatibility with JavaBean specification.

like image 106
Tomasz Nurkiewicz Avatar answered Oct 12 '22 17:10

Tomasz Nurkiewicz


There are basically two different philosophies when unit-testing.

  • Testing the state of your class under test. You typically run the method you want to test, and check that the class under test has the correct state after it ran, using getters on it, or the value being returned by the method itself. In this scenario, it may be a bit difficult to test a void method, as you may be forced to add getters just for your test, and it would break encapsulation. So don't do that. An alternate way is to use state-capturing stub classes as your dependencies, but this can be fishy as your stub themselves contain some untested logic.

  • Testing the behaviour of your class under test. While running the method you want to test, you set expectations on the dependencies of your class. This is typically achieved using mock frameworks. In this scenario, you basically don't care whether your method return a value, or is void. What's important is what methods are being called on your dependencies, and with which parameters. This is what you want to do, a far more efficient way of testing (and usually provides better coverage). Using this way of testing consistently also ensures your design is good and proper OO (forces you to do dependency injection, etc.)

like image 40
Guillaume Avatar answered Oct 12 '22 18:10

Guillaume