← 返回首页

微服务测试策略

📂 java ⏱ 2 min 291 words

微服务测试策略

概述

微服务架构需要多层次的测试策略。本教程介绍单元测试、集成测试和端到端测试。

1. 单元测试

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
    @Mock
    private UserRepository userRepository;
    
    @Mock
    private MessageService messageService;
    
    @InjectMocks
    private UserService userService;
    
    @Test
    void testCreateUser() {
        User user = new User("Alice", 25);
        when(userRepository.save(any(User.class))).thenReturn(user);
        
        User created = userService.createUser(user);
        
        assertNotNull(created);
        assertEquals("Alice", created.getName());
        verify(userRepository, times(1)).save(any(User.class));
        verify(messageService, times(1)).sendWelcomeEmail(eq("Alice"));
    }
    
    @Test
    void testCreateUser_InvalidAge() {
        User user = new User("Bob", -1);
        
        assertThrows(ValidationException.class, () -> {
            userService.createUser(user);
        });
    }
}

2. 集成测试

import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@Testcontainers
@ActiveProfiles("test")
public class UserRepositoryTest {
    @Container
    static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
        .withDatabaseName("testdb")
        .withUsername("test")
        .withPassword("test");
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    void testSaveAndFind() {
        User user = new User("Alice", 25);
        User saved = userRepository.save(user);
        
        User found = userRepository.findById(saved.getId()).orElse(null);
        
        assertNotNull(found);
        assertEquals("Alice", found.getName());
    }
}

3. 端到端测试

import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.*;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest {
    @Autowired
    private TestRestTemplate restTemplate;
    
    @Test
    void testCreateAndRetrieveUser() {
        // 创建用户
        User user = new User("Alice", 25);
        ResponseEntity<User> createResponse = restTemplate.postForEntity(
            "/api/users", user, User.class);
        
        assertEquals(HttpStatus.OK, createResponse.getStatusCode());
        assertNotNull(createResponse.getBody().getId());
        
        // 获取用户
        Long userId = createResponse.getBody().getId();
        ResponseEntity<User> getResponse = restTemplate.getForEntity(
            "/api/users/" + userId, User.class);
        
        assertEquals(HttpStatus.OK, getResponse.getStatusCode());
        assertEquals("Alice", getResponse.getBody().getName());
    }
}

4. 实际应用示例

Contract Testing

import org.springframework.cloud.contract.spec.Contract;

Contract.make {
    request {
        method 'GET'
        url '/api/users/1'
    }
    response {
        status 200
        body (
            id: 1,
            name: "Alice",
            age: 25
        )
    }
}

Performance Testing

import io.gatling.javaapi.core.*;
import io.gatling.javaapi.http.*;
import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.*;

public class UserPerformanceTest extends Simulation {
    HttpProtocolBuilder httpProtocol = http
        .baseUrl("http://localhost:8080")
        .acceptHeader("application/json");
    
    ScenarioBuilder userScenario = scenario("User Scenario")
        .exec(http("Get User")
            .get("/api/users/1")
            .check(status().is(200)));
    
    {
        setUp(userScenario.injectOpen(atOnceUsers(100)))
            .protocols(httpProtocol);
    }
}

5. 最佳实践

  1. 测试金字塔:单元测试 > 集成测试 > 端到端测试
  2. 使用Testcontainers:容器化测试环境
  3. Mock外部依赖:使用Mock隔离外部服务
  4. 契约测试:确保服务间接口一致性
  5. 性能测试:定期进行性能测试

总结

微服务架构需要多层次的测试策略。掌握单元测试、集成测试和端到端测试,可以确保微服务系统的质量。