Files
jaxwsdemo/TEST_GUIDE.md

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

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:

  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

# 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:

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:

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:

  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

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.