AssertTrue
AssertTrue, takes a boolean as a parameter. This is the simplest of all.
It checks if the expression is true.
Assert.assertTrue(true);
OBS: Recommends If you use a minimum of negative expressions.
AssertFalse
AssertFalse validates whether the expression is false.
assertFalse(false);
AssertEquals
Its operation is very simple, it validates if the expected value is equal to the current one.
assertEquals(expectedValue, current);
To use Equals to compare decimal places, use the comparison delta.
The delta would be a margin of error for comparison.
assertEquals(expectedValue, current, delta);
Example:
assertEquals(0.51, 0.51, 0.01);
AssertThat
Basically AssethThat means, verify that.
In assertThat and the inverse of assertEqual, the first value and the current, the second and the match.
Here is checking if the expected value is equal to 5.0
asserthThat(allocation.getValue(), CoreMatchers.is(5.0));
another way to do
assethThat(allocation.getValue(), is(equalsTo(5.0)));
Denial: Check that negation value, not and 6.
assethThat(allocation.getValue(), is(not(6.0)));
With Date: Checks if the date is true.
assethThat(allocation.getValue(), new Date(), is(true));
OBS: Ideally, for each test there is an assertion.
Rule
With rule you can do several tests and just one, thus losing the need to split tests.
Example:
@Rule
public ErrorCollector erro = new ErrorCollector();
erro.checkThat(allocation.getValue(), is(equalsTo(6.0)));
erro.checkThat(isMesmaData(allocation.getDateAllocation(), new Date()), is(true));
In this example above, unlike an AssethThat, it will check one by one, even if it fails.
Making sure you don't fail
@Rule
public ErroCollector error = new ErroCollector();
@Test
public void testAllocation() {
// Scenery
AllocationService service = new AllocationService();
User user = new User("User !");
Movie movie = new Movie("Movie 1", 2, 5.0);
// Action
try {
service.rentMovie(user, movie);
Assert.fail("Should have thrown an exception");
} cathc (Exception e) {
assertThat(e.getMessage(), is("Film out of stock"));
}
}
To ensure that a test passes and does not fail, you can create a try catch with Assert.fail.
The safest way to work with exceptions is with try catch.
Another way of working with exceptions.
@Rule
public ExpectedException execption = ExpectedException.none();
@Test
public void testAllocation() {
// Scenery
AllocationService service = new AllocationService();
User user = new User("User !");
Movie movie = new Movie("Movie 1", 2, 5.0);
// Action
service.rentMovie(user, movie);
exception.expect(Excption.class);
exception.expectMessage("Film out of stock");
}
Another way is also with expected. In the method header, inside the @test annotation. So it will catch the exception described inside.
@Test(expected = FilmOutOfStockException.class)
public void testAllocation() throws Exception {
Another way to test and verify posted messages.
if (movie == null) {
throw new LessorException("Empty user");
}
Here will capture the message when exception was thrown:
exception.expect(LessorException.class);
exception.expectMessage("Empty user");
Before and After
There are two annotations that allow code blocks to be executed before and after each test.
First one and @Before. With it it is possible that it is executed first, before the test. Follow the example below.
@Before
public void setup() {
System.out.println("before");
}
Another is @After, it runs after each test.
@After
public void setup() {
System.out.println("after");
}
The @Before and @After are executed one by one for each test, over and over again.
An example of using @Before would be to initialize common classes between tests.
Example:
private AllocationService service;
@Before
public void setup() {
service = new AllocationService();
}
Another way also to initialize is with BeforeClass and AfterClass, which is initialized after and before the class is initialized or terminated. Their implementation is similar to Before, however the method containing this annotation must be static*.
@BeforeClass
public static void setup() {
System.out.println("before class");
}
OBS: Static variables in class scope JUnit does not reset.
Running tests in order
To run the tests in order, you must create the methods without the @test annotation. This creates a general test to run. Below is an example.
public static counter = 0;
public void start() {
counter = 1;
}
public void check() {
Assert.assertEqual(1, counter);
}
@Test
public void testAll() {
start();
check();
}
This way it is guaranteed that the start() method will be executed first and then check().
There is another way to do this, which is the most suitable way and with @FixMethodOrder() annotation, which is used in the class header.
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OrderTest() {
public static counter = 0;
@Test
public void t1_start() {
counter = 1;
}
@Test
public void t2_check() {
Assert.assertEqual(1, counter);
}
In this example the test methods were executed in alphabetical order, however there are other ways to define this execution route.
@Ignore and Assumptions
With @Ignore, we can ignore unwanted tests.
@Test
@Ignorer
public void shouldTest() {
}
Another way is using Assumptions, an example of its use and defining that the test would only be executed on a Saturday.
@Test
public void shouldTest() {
Assume.assumeTrue(DataUtils.checkDayOfWeek(new Date(), Calendar.SATURDAY));
}
Parameterized tests
Junit provides a way to parameterize tests, which is called parametrizer, with it it is possible to reduce the number of repeated lines of code in tests.
To initialize it, we must put it at the top of the class, being it @RunWith(Parameterized.class). That way JUnit already knows that the test of this class will be parameterized.
Next step now is to define the dataset that will be tested. In the getParametros method, which will be the data source, we must inform this to JUnit. For this we must use the annotation @Parameters, don't forget that and in the plural.
OBS: The parameters method must always be static.
Next step now is to define the link of the variables that are used in the getParameters method, they are filmes and AllocationValue.
OBS: These variables must be public, otherwise it will give access error.
@RunWith(Parameterized.class)
public class CalcValueAllocationTest {
private AllocationService service;
@Parameter
public List<Movie> movies;
@Parameter(value=1)
public Double valueAllocation;
@Before
public void setup() {
service = new AllocationService();
}
private static Movie movie1 = new Movie("Movie 1", 2, 4.0);
private static Movie movie2 = new Movie("Movie 2", 2, 4.0);
private static Movie movie3 = new Movie("Movie 3", 2, 4.0);
private static Movie movie4 = new Movie("Movie 4", 2, 4.0);
private static Movie movie5 = new Movie("Movie 5", 2, 4.0);
private static Movie movie6 = new Movie("Movie 6", 2, 4.0);
@Parameters
public static Collection<Object[]> getParameters() {
return Arrays.asList(new Object[][] {
{Arrays.asList(movie1, movie2, movie3), 11.0},
{Arrays.asList(movie1, movie2, movie3, movie4), 13.0},
{Arrays.asList(movie1, movie2, movie3, movie4, movie5), 14.0},
{Arrays.asList(movie1, movie2, movie3, movie4, movie5, movie6), 14.0}
});
}
@Test
public void mustCalculateLeaseValueConsideringDiscounts() throws OutofStockFilmException, RentalCompanyException {
// Scenery
User user = new User("User 1");
// Action
Allocation result = service.alugarFilme(user, movie);
// Check
assertThat(result.getValue(), is(valueRentalCompany));
}
}
Test Suite
First of all, to use the suite, you must create a class for it, because it is where the other tests will be called.
In @RunWith(Suite.class) we tell JUnit that our test will be initialized as a suite.
In the annotation @SuiteClass({}), it is defined all the tests that will be executed by this suite. Inside it will be placed all the classes that must be tested.
@RunWith(Suite.class)
@SuiteClass({
CalculatorTest.class,
CalcValueRentalCompany.class,
RentalCompanyServiceTest.class
})
public class SuiteExecution {
}
InjectMocks
With the @InjectMocks annotation, it creates an instance of the class and injects the mocks that are created with the @Mock annotation or in this instance @spy. And for that, you must also use @RunWith(MockitoJunitRunner.class) or Mockito.initMocks(this) to initialize these mocks and inject them.
Spy
The annotation @spy is similar to @Mock but in reverse.
Mock it returns the default value, while Spy returns the method execution.
OBS: @spy does not work with interface, only with concrete classes.``
Top comments (0)