setup tests for HelloWorldService
This commit is contained in:
346
TEST_GUIDE.md
Normal file
346
TEST_GUIDE.md
Normal file
@ -0,0 +1,346 @@
|
||||
# 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
|
||||
```cmd
|
||||
run-tests.bat
|
||||
```
|
||||
|
||||
#### Linux/Mac
|
||||
```bash
|
||||
./run-tests.sh
|
||||
```
|
||||
|
||||
### Run Tests with Maven (Local)
|
||||
|
||||
If you have Maven installed locally:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
1. **testGetHelloWorld_WithValidName** - Verifies greeting with valid name
|
||||
2. **testGetHelloWorld_WithEmptyString** - Handles empty string input
|
||||
3. **testGetHelloWorld_WithNull** - Handles null input gracefully
|
||||
4. **testGetHelloWorld_WithSpecialCharacters** - Handles special characters
|
||||
5. **testGetHelloWorld_WithSpaces** - Handles names with spaces
|
||||
6. **testGetHelloWorld_WithLongName** - Handles long names
|
||||
7. **testGetHelloWorld_ReturnsNonNull** - Ensures non-null response
|
||||
8. **testGetHelloWorld_StartsWithHelloWorld** - Verifies message format
|
||||
9. **testGetHelloWorld_EndsWithExclamation** - Verifies message ending
|
||||
10. **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 `tester` stage of the Dockerfile
|
||||
- Mount source code for live testing
|
||||
- Cache Maven dependencies for faster subsequent runs
|
||||
- Set appropriate memory limits
|
||||
|
||||
### Run Tests Manually
|
||||
|
||||
```bash
|
||||
# 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 assertions
|
||||
- `junit-jupiter-engine:5.9.3` - Test execution engine
|
||||
|
||||
- **Mockito** - Mocking framework (for future complex tests)
|
||||
- `mockito-core:5.3.1` - Core mocking functionality
|
||||
- `mockito-junit-jupiter:5.3.1` - JUnit 5 integration
|
||||
|
||||
- **Maven Surefire** - Test runner plugin
|
||||
- Configured to run all `*Test.java` files
|
||||
|
||||
## Writing New Tests
|
||||
|
||||
### Test Structure
|
||||
|
||||
Tests follow the standard JUnit 5 structure:
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
1. **Use Descriptive Names**: Use `@DisplayName` for readable test descriptions
|
||||
2. **Follow AAA Pattern**: Arrange, Act, Assert
|
||||
3. **Test Edge Cases**: Include null, empty, and boundary conditions
|
||||
4. **Keep Tests Isolated**: Each test should be independent
|
||||
5. **Test One Thing**: Each test should verify one specific behavior
|
||||
|
||||
### Adding Tests for New Services
|
||||
|
||||
To add tests for other services (e.g., LoanApprovalService):
|
||||
|
||||
1. Create test class in `src/test/java/com/example/service/`
|
||||
2. Follow the naming convention: `{ServiceName}Test.java`
|
||||
3. Run tests to verify
|
||||
|
||||
Example structure for LoanApprovalService tests:
|
||||
|
||||
```java
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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**:
|
||||
```bash
|
||||
# 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**:
|
||||
```bash
|
||||
# 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**:
|
||||
```bash
|
||||
chmod +x run-tests.sh
|
||||
./run-tests.sh
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Consider adding tests for:
|
||||
|
||||
1. **LoanApprovalService**
|
||||
- Customer registration workflows
|
||||
- Loan approval logic
|
||||
- Credit score evaluation
|
||||
- Blacklist handling
|
||||
|
||||
2. **Repository Layer**
|
||||
- Database operations
|
||||
- CRUD functionality
|
||||
- Error handling
|
||||
|
||||
3. **Integration Tests**
|
||||
- End-to-end SOAP request/response
|
||||
- Database integration
|
||||
- Multi-service workflows
|
||||
|
||||
4. **Performance Tests**
|
||||
- Load testing
|
||||
- Stress testing
|
||||
- Response time validation
|
||||
|
||||
## Resources
|
||||
|
||||
- [JUnit 5 User Guide](https://junit.org/junit5/docs/current/user-guide/)
|
||||
- [Mockito Documentation](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html)
|
||||
- [Maven Surefire Plugin](https://maven.apache.org/surefire/maven-surefire-plugin/)
|
||||
- [Test-Driven Development Best Practices](https://martinfowler.com/bliki/TestDrivenDevelopment.html)
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user