微服务测试策略
微服务测试策略
概述
微服务架构需要多层次的测试策略。本教程介绍单元测试、集成测试和端到端测试。
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. 最佳实践
- 测试金字塔:单元测试 > 集成测试 > 端到端测试
- 使用Testcontainers:容器化测试环境
- Mock外部依赖:使用Mock隔离外部服务
- 契约测试:确保服务间接口一致性
- 性能测试:定期进行性能测试
总结
微服务架构需要多层次的测试策略。掌握单元测试、集成测试和端到端测试,可以确保微服务系统的质量。