8.3 KiB
Unit Testing Guide
This guide explains how to run and write unit tests for the JAX-WS Hello World Service project.
Quick Start
Run Tests with Docker (Recommended)
Windows
run-tests.bat
Linux/Mac
./run-tests.sh
Run Tests with Maven (Local)
If you have Maven installed locally:
mvn test
Test Results Summary
Current Test Coverage
| Service | Test Class | Test Cases | Status |
|---|---|---|---|
| Hello World Service | HelloWorldServiceImplTest | 10 | ✅ Passing |
Test Case Details
The HelloWorldServiceImplTest includes the following test cases:
- testGetHelloWorld_WithValidName - Verifies greeting with valid name
- testGetHelloWorld_WithEmptyString - Handles empty string input
- testGetHelloWorld_WithNull - Handles null input gracefully
- testGetHelloWorld_WithSpecialCharacters - Handles special characters
- testGetHelloWorld_WithSpaces - Handles names with spaces
- testGetHelloWorld_WithLongName - Handles long names
- testGetHelloWorld_ReturnsNonNull - Ensures non-null response
- testGetHelloWorld_StartsWithHelloWorld - Verifies message format
- testGetHelloWorld_EndsWithExclamation - Verifies message ending
- testGetHelloWorld_ContainsName - Verifies name inclusion
Docker Test Configuration
Test Architecture
The project uses a multi-stage Dockerfile:
- Stage 1 (tester): Runs unit tests
- Stage 2 (builder): Builds the WAR file
- Stage 3: Deploys to Tomcat
Test Docker Compose
The docker-compose.test.yml file is configured to:
- Target the
testerstage of the Dockerfile - Mount source code for live testing
- Cache Maven dependencies for faster subsequent runs
- Set appropriate memory limits
Run Tests Manually
# Build and run tests
docker-compose -f docker-compose.test.yml up --build
# Clean up after tests
docker-compose -f docker-compose.test.yml down
Testing Framework
Dependencies
The project uses:
-
JUnit 5 (Jupiter) - Testing framework
junit-jupiter-api:5.9.3- Test annotations and assertionsjunit-jupiter-engine:5.9.3- Test execution engine
-
Mockito - Mocking framework (for future complex tests)
mockito-core:5.3.1- Core mocking functionalitymockito-junit-jupiter:5.3.1- JUnit 5 integration
-
Maven Surefire - Test runner plugin
- Configured to run all
*Test.javafiles
- Configured to run all
Writing New Tests
Test Structure
Tests follow the standard JUnit 5 structure:
package com.example.service;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;
@DisplayName("Service Tests")
class YourServiceTest {
private YourService service;
@BeforeEach
void setUp() {
service = new YourServiceImpl();
}
@Test
@DisplayName("Should do something")
void testSomething() {
// Arrange
String input = "test";
String expected = "expected result";
// Act
String result = service.doSomething(input);
// Assert
assertEquals(expected, result);
}
}
Test Best Practices
- Use Descriptive Names: Use
@DisplayNamefor readable test descriptions - Follow AAA Pattern: Arrange, Act, Assert
- Test Edge Cases: Include null, empty, and boundary conditions
- Keep Tests Isolated: Each test should be independent
- Test One Thing: Each test should verify one specific behavior
Adding Tests for New Services
To add tests for other services (e.g., LoanApprovalService):
- Create test class in
src/test/java/com/example/service/ - Follow the naming convention:
{ServiceName}Test.java - Run tests to verify
Example structure for LoanApprovalService tests:
package com.example.service;
import com.example.model.*;
import com.example.repository.*;
import org.junit.jupiter.api.*;
import org.mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@DisplayName("LoanApprovalService Tests")
class LoanApprovalServiceTest {
@Mock
private CustomerRepository customerRepository;
@Mock
private CreditScoreService creditScoreService;
private LoanApprovalService service;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
service = new LoanApprovalService();
// Inject mocks if needed
}
@Test
@DisplayName("Should approve loan for high credit score")
void testLoanApproval_HighCreditScore() {
// Test implementation
}
}
Test Directory Structure
src/
├── main/
│ └── java/
│ └── com/
│ └── example/
│ └── service/
│ ├── HelloWorldService.java
│ └── HelloWorldServiceImpl.java
└── test/
└── java/
└── com/
└── example/
└── service/
└── HelloWorldServiceImplTest.java
Continuous Integration
Running Tests in CI/CD
The Dockerfile includes testing as the first stage, which means:
- Tests run automatically during Docker build
- Build fails if tests fail
- Ensures code quality before deployment
To run tests in CI/CD pipelines:
# Option 1: Run full build (includes tests)
docker build -t jaxws-app .
# Option 2: Run tests only
docker build --target tester -t jaxws-test .
# Option 3: Use docker-compose
docker-compose -f docker-compose.test.yml up --abort-on-container-exit
Viewing Test Reports
Console Output
Test results are displayed in the console with summary:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.example.service.HelloWorldServiceImplTest
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.024 s
Results:
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
Surefire Reports
Maven Surefire generates detailed reports in:
target/surefire-reports/(text and XML formats)
Troubleshooting
Tests Not Running
Problem: Maven doesn't find tests
Solution:
- Ensure test files end with
Test.java - Verify test directory structure:
src/test/java/ - Check pom.xml includes maven-surefire-plugin
Docker Build Fails on Tests
Problem: Docker build fails at test stage
Solution:
# View detailed test output
docker build --target tester -t jaxws-test .
# Check test container logs
docker logs <container-id>
Dependency Issues
Problem: Cannot resolve JUnit dependencies
Solution:
# Clear Maven cache and rebuild
docker-compose -f docker-compose.test.yml build --no-cache
Permission Denied on run-tests.sh
Problem: Cannot execute run-tests.sh on Linux/Mac
Solution:
chmod +x run-tests.sh
./run-tests.sh
Future Enhancements
Consider adding tests for:
-
LoanApprovalService
- Customer registration workflows
- Loan approval logic
- Credit score evaluation
- Blacklist handling
-
Repository Layer
- Database operations
- CRUD functionality
- Error handling
-
Integration Tests
- End-to-end SOAP request/response
- Database integration
- Multi-service workflows
-
Performance Tests
- Load testing
- Stress testing
- Response time validation
Resources
- JUnit 5 User Guide
- Mockito Documentation
- Maven Surefire Plugin
- Test-Driven Development Best Practices
Summary
This project now has a complete unit testing setup with:
- ✅ JUnit 5 testing framework
- ✅ 10 passing test cases for HelloWorldService
- ✅ Docker-based test execution
- ✅ Convenient test runner scripts
- ✅ Multi-stage Dockerfile with test stage
- ✅ Maven Surefire configuration
- ✅ Mockito for future mocking needs
To add more tests, simply create new test classes following the established patterns and run them using the provided scripts.