Welcome to the Ultimate Java Testing Guide! π In this project, we're mastering JUnit for unit testing and Mockito for mocking dependencies. Whether you're a beginner or want to refine your skills, this repository will help you write clean, maintainable, and well-tested Java code. π§βπ»π§ͺ
- Introduction
- What You'll Learn
- Setup & Installation
- Understanding Unit Testing
- Writing Your First Test
- Mocking with Mockito
- Best Practices
- Running the Tests
- Screenshots
- More Learning Resources
- Contributors
- License
Unit testing is the backbone of high-quality software development. With JUnit, we can create repeatable and automated tests to ensure our code behaves as expected. Mockito takes it a step further by allowing us to mock dependencies, which means we can isolate components and test them in controlled environments.
This project is designed to give you hands-on experience with:
- π§ͺ JUnit 5 β The modern unit testing framework for Java.
- π§ Mockito β The most popular mocking framework in the Java ecosystem.
- π Test-driven development (TDD) β Writing tests before implementing functionality.
- β Assertion techniques β Making sure your tests are robust and reliable.
- π Mocking strategies β Simulating complex interactions with external dependencies.
Before diving into testing, make sure you have the following installed on your machine:
- Java 17 or higher π’
- Download from the Oracle website.
- Maven or Gradle for dependency management π οΈ
- JUnit 5 and Mockito libraries.
If you're using Maven, add these dependencies to your pom.xml
:
<dependencies>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
</dependencies>
Hereβs the full README file with the updated sections for More Learning Resources, Contributions, License, and Contributors:
Before diving into testing, make sure you have the following installed on your machine:
- Java 17 or higher π’
- Download from the Oracle website.
- Maven or Gradle for dependency management π οΈ
- JUnit 5 and Mockito libraries.
If you're using Maven, add these dependencies to your pom.xml
:
<dependencies>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
</dependencies>
If you're using Gradle, add the following to your build.gradle:
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
testImplementation 'org.mockito:mockito-core:3.12.4'
}
Unit tests focus on individual pieces of functionality in your application, typically a method or class. The goal is to ensure that these small units work as expected. A typical unit test:
1-Sets up necessary data or dependencies. 2-Executes the method to be tested. 3-Asserts that the result matches the expected outcome.
Unit tests should be:
-Fast β Run in milliseconds. -Isolated β No reliance on external systems like databases or network services. -Repeatable β Produce the same result every time.
Let's start simple! Imagine you have a Calculator class that adds two numbers. Here's how you'd test it using JUnit. Unit tests focus on individual pieces of functionality in your application, typically a method or class. The goal is to ensure that these small units work as expected. A typical unit test:
Sets up necessary data or dependencies. Executes the method to be tested. Asserts that the result matches the expected outcome. Unit tests should be:
Fast β Run in milliseconds. Isolated β No reliance on external systems like databases or network services. Repeatable β Produce the same result every time.
Let's start with a straightforward example! Suppose you have a Calculator
class that adds two numbers. Here's how you would test it using JUnit.
public class Calculator {
public int add(int a, int b) {
return a + b;
}
}
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@Test
public void testAddition() {
Calculator calculator = new Calculator();
int result = calculator.add(2, 3);
assertEquals(5, result, "The addition result should be 5");
}
}
Explanation:
@Test: Marks the method as a unit test. assertEquals(expected, actual): Checks if the actual result matches the expected result.
Unit tests should focus on the class itself, but sometimes our classes depend on external systems (e.g., databases, web services). This is where Mockito helps by mocking those dependencies.
Example: OrderProcessor Class
public class OrderProcessor {
private PaymentService paymentService;
public OrderProcessor(PaymentService paymentService) {
this.paymentService = paymentService;
}
public boolean processOrder() {
return paymentService.processPayment();
}
}
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class OrderProcessorTest {
@Test
public void testProcessOrder() {
// Mock the PaymentService
PaymentService paymentService = Mockito.mock(PaymentService.class);
Mockito.when(paymentService.processPayment()).thenReturn(true);
// Test the OrderProcessor with the mock
OrderProcessor processor = new OrderProcessor(paymentService);
boolean result = processor.processOrder();
assertTrue(result, "The order should be processed successfully");
}
}
Explanation:
Mockito.mock(): Creates a mock object. Mockito.when().thenReturn(): Specifies the behavior of the mock. assertTrue(result): Ensures that the order processing was successful.
To write effective unit tests:
- Test One Thing: Each test should verify one behavior or result.
- Keep It Short: Your test methods should be concise and to the point.
- Use Meaningful Names: Test names should describe the behavior being tested.
- Mock Only What You Need: Donβt mock everythingβonly mock external dependencies or slow operations.
- Use Setup Methods: If tests require repeated setup, use
@BeforeEach
to avoid redundancy.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
private Calculator calculator;
@BeforeEach
public void setup() {
calculator = new Calculator();
}
@Test
public void testAddition() {
assertEquals(5, calculator.add(2, 3));
}
}
-
Clone the repo:
git clone https://github.com/yourusername/junit-mockito-example.git
-
Open the project in your IDE (IntelliJ, Eclipse, etc.).
-
Navigate to the test folder.
-
Right-click and select Run All Tests.
If you're using Maven, you can run the tests from the command line:
mvn test
Feel free to open issues or pull requests if you'd like to contribute! Let's make this project better together π±β¨.
This project is licensed under the MIT License. See the LICENSE file for details.
A big thank you to everyone who has contributed to this project:
- Douaa Chemnane β Initial work and documentation.
- GitHub: Douaa19819