Share this blog!

 

Parameterized tests are extremely useful when you need to test a series of inputs against the same functionality. JUnit offers Parameterized class that facilitates this purpose. 


As usual, let's go through an example. 


Assume you have a simple add method that takes 2 Integers and returns their sum. The Parameterized test for a such implementation would be: 


@RunWith(Parameterized.class)
public class AdderTest extends TestCase {

@Parameterized.Parameters(name = "{index}: add[{0}, {1}]={2}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{0, 0, 0},
{1, 1, 2},
{2, 1, 3},
{100, 400, 500},
{99, 1, 100}
});
}


int input1;
int input2;
int expectedOutput;

public AdderTest(int i1, int i2, int expected) {
input1 = i1;
input2 = i2;
expectedOutput = expected;
}

@Test
public void testAdd() {
assertEquals(expectedOutput, Computer.add(input1, input2));
}

}


The test class constructor takes 3 arguments, the first input number, the second input number and the expected output respectively. 


The data() method returns an array of 5 of objects, each containing 3 Integers. 


During runtime, AdderTest will be instantiated 5 times, with the corresponding elements returned in the data() method. 


The @Parameters annotation can be fed with a name, so that each test can be easily identified. The name contains placeholders for each parameter. Additionally, an "index" placeholder will keep track of the current parameter index. 


When the test class is executed, the results will look like:




If the test method requires only a single argument, there is no need to wrap it in an array and can be implemented as shown below:


@Parameterized.Parameters
public static Object[] data() {
return new Object[]{"first test", "second test"};
}


or


@Parameterized.Parameters
public static Iterable<? extends Object> data() {
return Arrays.asList("first test", "second test");
}


Cheers!



Mockito has a list of uniquely useful components and ArgumentCaptor is one such example. 


As the name suggests, ArgumentCaptor can be used to examine arguments passed onto methods, which cannot be accessed otherwise. 


Let's assume we have a Util class as follows that simply prints whatever String argument is passed onto it. 


public class Util {

public void shoutOut(String lifeQuote) {
System.out.println(lifeQuote);
}
}


Then let's assume we have another class Dog that will be calling the Util's method:


public class Dog {

private Util util;

public Dog(Util util) {
this.util = util;
}

public void bark() {
String lifeQuote = "I'm awesome";
this.util.shoutOut(lifeQuote);
}
}


In this kind of scenario, we wouldn't have a way to test if the method shoutOut actually prints the desired life quote.


This is where ArgumentCaptor becomes useful as follows.

Some important points to notice:
  • The object Util needs to be mocked since the argument to be tested is passed onto a method in it
  • The ArgumentCaptor needs to be instantiated using the object type of the argument that is to be tested
  • The verify method should be called on the mocked object

import junit.framework.TestCase;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class DogTest extends TestCase {

@Test
public void testBark() {

// The argument to be tested should be called on a mocked class
// i.e. we need to test the "lifeQuote" argument passed onto "Util" method "shoutOut"
// therefore we should mock the Util class
Util utilMock = mock(Util.class);

Dog toby = new Dog(utilMock);
toby.bark();

// We need to create a captor to capture the argument
// In our case, the captured argument is of type String
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

// Verify that the captor is used in the mocked method
verify(utilMock).shoutOut(captor.capture());

// Retrieve the captured value
String updatedLifeQuote = captor.getValue();

// Assert if the value is as expected
assertEquals("I'm awesome", updatedLifeQuote);
}

}

Cheers!
Next PostNewer Posts Previous PostOlder Posts Home