Unit Test
1. Gradle Dependencies:
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.2'
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.2'
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.10.2'
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.10.2'
this will replace all of them:
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
Mockito dependency:
// https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter
testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '5.11.0'
package az.etibarli.mockito1;
public class Calculator {
public int integerDivision(int dividend, int divisor) {
return dividend / divisor;
}
public int integerSubtraction(int minuend, int subtrahend) {
return minuend - subtrahend;
}
}
package az.etibarli.mockito1;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@Test
void integerDivision() {
Calculator calculator = new Calculator();
int result = calculator.integerDivision(4, 2);
assertEquals(2, result, "4 divided by 2 success");
}
@Test
void integerSubtraction() {
Calculator calculator = new Calculator();
int minuend = 33;
int subrahend = 1;
int expectedResult = 34;
int actualResult = calculator.integerSubtraction(minuend, subrahend);
assertEquals(expectedResult, actualResult,
() -> minuend + "-" + subrahend + " did not produce " + expectedResult);
}
}
Different types of tests:
package az.etibarli.mockito1;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@DisplayName("Test Math operation in Calculator class")
public class CalculatorTest {
Calculator calculator;
@BeforeAll
static void setup() {
System.out.println("Executing @BeforeAll method.");
}
@AfterAll
static void cleanup() {
System.out.println("Executing @AfterAll method.");
}
@BeforeEach
void beforeEachTestMethod() {
calculator = new Calculator();
System.out.println("Executing @BeforeEach method");
}
@AfterEach
void afterEachTestMethod() {
System.out.println("Executing @AfterEach method.");
}
@Test
@DisplayName("4 / 2 = 2")
void testIntegerDivision_WhenFourIsDividedByTwo_ShouldReturnTwo() {
System.out.println("Running 4 / 2");
// arrange = given
int dividend = 4;
int divisor = 2;
int expectedResult = 2;
// act = when
int actualResult = calculator.integerDivision(dividend, divisor);
// assert = then
assertEquals(expectedResult, actualResult, "4 divided by 2 success");
}
@Test
// @Disabled("TODO: need to be fixed")
@DisplayName("Division by zero")
void testIntegerDivision_WhenDividendIsDividedByZero_ShouldThrowArithmeticException() {
// arrange = given
int dividend = 4;
int divisor = 1;
String expectedExceptionMessage = "/ by zero";
// act & assert
ArithmeticException actualException = assertThrows(ArithmeticException.class, () -> {
calculator.integerDivision(dividend, divisor);
}, "exception");
// assert
assertEquals(expectedExceptionMessage, actualException.getLocalizedMessage(),
"Unexpected exception message");
}
// @Test
@DisplayName("Test 33 - 1 = 32")
@ParameterizedTest
@MethodSource("integerSubtractionInputParameters")
void integerSubtraction(int minuend, int subtrahend, int expectedResult) {
int actualResult = calculator.integerSubtraction(minuend, subtrahend);
assertEquals(expectedResult, actualResult,
() -> minuend + "-" + subtrahend + " did not produce " + expectedResult);
}
private static Stream<Arguments> integerSubtractionInputParameters() {
return Stream.of(
Arguments.of(33, 1, 32),
Arguments.of(24, 1, 23)
);
}
}
another example:
package az.etibarli.mockito1;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("Test Math operation in Calculator class")
public class CalculatorTest {
Calculator calculator;
@BeforeAll
static void setup() {
System.out.println("Executing @BeforeAll method.");
}
@AfterAll
static void cleanup() {
System.out.println("Executing @AfterAll method.");
}
@BeforeEach
void beforeEachTestMethod() {
calculator = new Calculator();
System.out.println("Executing @BeforeEach method");
}
@AfterEach
void afterEachTestMethod() {
System.out.println("Executing @AfterEach method.");
}
@Test
@DisplayName("4 / 2 = 2")
void testIntegerDivision_WhenFourIsDividedByTwo_ShouldReturnTwo() {
System.out.println("Running 4 / 2");
// arrange = given
int dividend = 4;
int divisor = 2;
int expectedResult = 2;
// act = when
int actualResult = calculator.integerDivision(dividend, divisor);
// assert = then
assertEquals(expectedResult, actualResult, "4 divided by 2 success");
}
@Test
// @Disabled("TODO: need to be fixed")
@DisplayName("Division by zero")
void testIntegerDivision_WhenDividendIsDividedByZero_ShouldThrowArithmeticException() {
// arrange = given
int dividend = 4;
int divisor = 1;
String expectedExceptionMessage = "/ by zero";
// act & assert
ArithmeticException actualException = assertThrows(ArithmeticException.class, () -> {
calculator.integerDivision(dividend, divisor);
}, "exception");
// assert
assertEquals(expectedExceptionMessage, actualException.getLocalizedMessage(),
"Unexpected exception message");
}
// @Test
@DisplayName("Test 33 - 1 = 32")
@ParameterizedTest
// @MethodSource("integerSubtractionInputParameters")
// @MethodSource
@CsvSource({"33, 1, 32", "24, 1, 23"})
void integerSubtraction(int minuend, int subtrahend, int expectedResult) {
int actualResult = calculator.integerSubtraction(minuend, subtrahend);
assertEquals(expectedResult, actualResult,
() -> minuend + "-" + subtrahend + " did not produce " + expectedResult);
}
@ParameterizedTest
@ValueSource(strings = {"John", "Kate", "Alice"})
void valueSourceDemonstration(String firstName) {
System.out.println(firstName);
assertNotNull(firstName);
}
private static Stream<Arguments> integerSubtraction() {
return Stream.of(
Arguments.of(33, 1, 32),
Arguments.of(24, 1, 23)
);
}
}
--- Repeated Tests:
package az.etibarli.mockito1;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class DemoRepeatedTest {
Calculator calculator;
@BeforeEach
void beforeEachTestMethod() {
calculator = new Calculator();
System.out.println("Executing @BeforeEach method.");
}
@RepeatedTest(3)
@DisplayName("Division by zero")
void testIntegerDivision_WhenDividendIsDividedByZero_ShouldThrowArithmeticException(
RepetitionInfo repetitionInfo, TestInfo testInfo) {
System.out.println("Running Division by zero");
System.out.println("Running " + testInfo.getTestMethod().get().getName());
System.out.println("Repetition # " + repetitionInfo.getCurrentRepetition() +
" of " + repetitionInfo.getTotalRepetitions());
// arrange = given
int dividend = 4;
int divisor = 0;
String expectedExceptionMessage = "/ by zero";
// act & assert
ArithmeticException actualException = assertThrows(ArithmeticException.class, () -> {
calculator.integerDivision(dividend, divisor);
}, "exception");
// assert
assertEquals(expectedExceptionMessage, actualException.getLocalizedMessage(),
"Unexpected exception message");
}
}
---Method Order: random
package az.etibarli.mockito1;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.Random.class)
public class MethodOrderedRandomlyTest {
@Test
void testA() {
System.out.println("Running test A");
}
@Test
void testB() {
System.out.println("Running test B");
}
@Test
void testC() {
System.out.println("Running test C");
}
@Test
void testD() {
System.out.println("Running test D");
}
}
---Method Order: Order by name
package az.etibarli.mockito1;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.MethodName.class)
public class MethodOrderedByNameTest {
@Test
void testD() {
System.out.println("Running test D");
}
@Test
void testA() {
System.out.println("Running test A");
}
@Test
void testB() {
System.out.println("Running test B");
}
@Test
void testC() {
System.out.println("Running test C");
}
}
--- Test instance: Per method
package az.etibarli.mockito1;
import org.junit.jupiter.api.*;
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MethodOrderedByOrderIndexTest {
StringBuilder completed = new StringBuilder("");
@AfterEach
void afterEach() {
System.out.println("The state of instance object is: " + completed);
}
@Order(1)
@Test
void testA() {
System.out.println("Running test A");
completed.append("1");
}
@Order(2)
@Test
void testB() {
System.out.println("Running test B");
completed.append("2");
}
@Order(3)
@Test
void testC() {
System.out.println("Running test C");
completed.append("3");
}
@Order(4)
@Test
void testD() {
System.out.println("Running test D");
completed.append("4");
}
}
--- Test instance: Per class
package az.etibarli.mockito1;
import org.junit.jupiter.api.*;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MethodOrderedByOrderIndexTest {
StringBuilder completed = new StringBuilder("");
@AfterEach
void afterEach() {
System.out.println("The state of instance object is: " + completed);
}
@Order(1)
@Test
void testA() {
System.out.println("Running test A");
completed.append("1");
}
@Order(2)
@Test
void testB() {
System.out.println("Running test B");
completed.append("2");
}
@Order(3)
@Test
void testC() {
System.out.println("Running test C");
completed.append("3");
}
@Order(4)
@Test
void testD() {
System.out.println("Running test D");
completed.append("4");
}
}
--- Simple test with data:
package az.etibarli.mockito1.io;
import java.util.Map;
public interface UsersDatabase {
void init();
void close();
Map save(String userId, Map userDetails);
Map update(String userId, Map user);
Map find(String userId);
void delete(String userId);
}
package az.etibarli.mockito1.io;
import java.util.HashMap;
import java.util.Map;
public class UsersDatabaseMapImpl implements UsersDatabase {
Map<String, Map> users;
@Override
public void init() {
users = new HashMap<>();
}
@Override
public void close() {
users = null;
}
@Override
public Map save(String userId, Map userDetails) {
return users.put(userId, userDetails);
}
@Override
public Map update(String userId, Map user) {
users.put(userId, user);
return users.get(userId);
}
@Override
public Map find(String userId) {
return users.get(userId);
}
@Override
public void delete(String userId) {
users.remove(userId);
}
}
package az.etibarli.mockito1.service;
import java.util.Map;
public interface UserService {
String createUser(Map userDetails);
Map updateUser(String userId, Map userDetails);
Map getUserDetails(String userId);
void deleteUser(String userId);
}
package az.etibarli.mockito1.service;
import az.etibarli.mockito1.io.UsersDatabase;
import java.util.Map;
import java.util.UUID;
public class UserServiceImpl implements UserService {
UsersDatabase usersDatabase;
public UserServiceImpl(UsersDatabase usersDatabase) {
this.usersDatabase = usersDatabase;
}
@Override
public String createUser(Map userDetails) {
String userId = UUID.randomUUID().toString();
userDetails.put("userId", userId);
usersDatabase.save(userId, userDetails);
return userId;
}
@Override
public Map updateUser(String userId, Map userDetails) {
Map existingUser = usersDatabase.find(userId);
if (existingUser == null) throw new IllegalArgumentException("User not found");
existingUser.put("firstName", userDetails.get("firstName"));
existingUser.put("lastName", userDetails.get("lastName"));
return usersDatabase.update(userId, existingUser);
}
@Override
public Map getUserDetails(String userId) {
return usersDatabase.find(userId);
}
@Override
public void deleteUser(String userId) {
Map existingUser = usersDatabase.find(userId);
if (existingUser == null) throw new IllegalArgumentException("User not found");
usersDatabase.delete(userId);
}
}
package az.etibarli.mockito1;
import az.etibarli.mockito1.io.UsersDatabase;
import az.etibarli.mockito1.io.UsersDatabaseMapImpl;
import az.etibarli.mockito1.service.UserService;
import az.etibarli.mockito1.service.UserServiceImpl;
import org.junit.jupiter.api.*;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class UserServiceImplTest {
UsersDatabase usersDatabase;
UserService userService;
String createdUserId = "";
@BeforeAll
void setUp() {
// Create & initialize database
usersDatabase = new UsersDatabaseMapImpl();
usersDatabase.init();
userService = new UserServiceImpl(usersDatabase);
}
@AfterAll
void cleanUp() {
// Close database
// Delete database
usersDatabase.close();
}
@Test
@Order(1)
@DisplayName("Create User works")
void testCreateUser_whenProvideWithValidDetails_returnsUserId() {
// arrange
Map<String, String> user = new HashMap<>();
user.put("firstName", "Sergey");
user.put("lastName", "Kargopolov");
// act
createdUserId = userService.createUser(user);
// assert
assertNotNull(createdUserId, "User id should not be null");
}
@Test
@Order(2)
@DisplayName("Update User works")
void testUpdateUser_whenProvideWithValidDetails_returnsUpdatedUserDetails() {
// arrange
Map<String, String> newUserDetails = new HashMap<>();
newUserDetails.put("firstName", "John");
newUserDetails.put("lastName", "kargopolov");
// act
Map updatedUserDetails = userService.updateUser(createdUserId, newUserDetails);
// assert
assertEquals(newUserDetails.get("firstName"), updatedUserDetails.get("firstName"),
"Returned value of user's first name is incorrect");
assertEquals(newUserDetails.get("lastName"), updatedUserDetails.get("lastName"),
"Returned value of user's last name is incorrect");
}
@Test
@Order(3)
@DisplayName("Find User works")
void testGetUserDetails_whenProvideWithValidUserId_returnsUserDetails() {
// act
Map userDetails = userService.getUserDetails(createdUserId);
// assert
assertNotNull(userDetails, "User details should not be null");
assertEquals(createdUserId, userDetails.get("userId"),
"Returned user details contains incorrect user id");
}
@Test
@Order(4)
@DisplayName("Delete User works")
void testDeleteUser_whenProvideWithValidUserId_returnsUserDetails() {
// act
userService.deleteUser(createdUserId);
// assert
assertNull(userService.getUserDetails(createdUserId), "User should not been found");
}
}
Комментарии
Отправить комментарий