Unit Testing Void Methods

Unit testing void methods?

If a method doesn't return anything, it's either one of the following

  • imperative - You're either asking the object to do something to itself.. e.g change state (without expecting any confirmation.. its assumed that it will be done)
  • informational - just notifying someone that something happened (without expecting action or response) respectively.

Imperative methods - you can verify if the task was actually performed. Verify if state change actually took place. e.g.

void DeductFromBalance( dAmount ) 

can be tested by verifying if the balance post this message is indeed less than the initial value by dAmount

Informational methods - are rare as a member of the public interface of the object... hence not normally unit-tested. However if you must, You can verify if the handling to be done on a notification takes place. e.g.

void OnAccountDebit( dAmount )  // emails account holder with info

can be tested by verifying if the email is being sent

Post more details about your actual method and people will be able to answer better.
Update: Your method is doing 2 things. I'd actually split it into two methods that can now be independently tested.

string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );

String[] can be easily verified by providing the first method with a dummy file and expected strings. The second one is slightly tricky.. you can either use a Mock (google or search stackoverflow on mocking frameworks) to mimic the DB or hit the actual DB and verify if the strings were inserted in the right location. Check this thread for some good books... I'd recomment Pragmatic Unit Testing if you're in a crunch.

In the code it would be used like

InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );

How to unit test a method which calls a void method?

You use the verify method:

verify(myRemovalService).removeData("Test1"));
verify(myRemovalService).removeData("Test2"));

Unit testing void controller and service methods

This code is quite simple so I'm not sure you need to unit test it. But if you want to, you can make use of your Mockito's mocks' verify method. For example when testing addProduct :

@InjectMocks
ProductService productService;

@Mock
ProductRepository productRepository;

// ...

@Test
public void testAddProduct() {
Product dummyProduct = new Product();

productService.addProduct(dummyProduct);

// eq() is from the Mockito matchers package
Mockito.verify(productRepository, Mockito.times(1)).save(eq(dummyProduct))
}

This verifies that save was called on time on the mocked repository with an argument of dummyProduct.

You also may want to check out Mockito "argument captors".

Should I write unit test for void methods (includes repository call)?

Yes. You should mainly focus on whether UserServiceImpl interacts with UserRepository in an expected way such as the things like if it invokes the correct method on the UserRepository with the correct arguments etc.

By using Mockito to mock the UserRepository , you may end up with a test something like as follows :

@ExtendWith(MockitoExtension.class)
public class UserServiceImplUnitTest {

@Mock
UserRepository userRepository ;

UserService userService;

@BeforeEach
void setup() {
userService = new UserServiceImpl(userRepository);
}

@Test
public void testSaveOrUpdateUser(){
UserDAO user = createDummyUser();
userService.saveOrUpdateUser(user);

verify(userRepository).save(same(user));
}
}

JUNIT testing void methods

I want to make some unit test to get maximal code coverage

Code coverage should never be the goal of writing unit tests. You should write unit tests to prove that your code is correct, or help you design it better, or help someone else understand what the code is meant to do.

but I dont see how I can test my method checkIfValidElements, it returns nothing or change nothing.

Well you should probably give a few tests, which between them check that all 7 methods are called appropriately - both with an invalid argument and with a valid argument, checking the results of ErrorFile each time.

For example, suppose someone removed the call to:

method4(arg1, arg2);

... or accidentally changed the argument order:

method4(arg2, arg1);

How would you notice those problems? Go from that, and design tests to prove it.

How to write unit test for void method with for loop and utilization of method from another class?

You could use a mocking framework like Mockito, EasyMock or PowerMock and create a mock for B, which you then assign to b in the instance of the class you want to test.

You can tell the mock which methods you expect to have called, which parameters you expect to be passed and then you can verify that all your expectations were fulfilled.

See the respective framework's documentation for an example of how to use them.



Related Topics



Leave a reply



Submit