Files
wenzi/src/test/java/com/mosquito/project/dto/CreateApiKeyResponseTest.java

427 lines
14 KiB
Java
Raw Normal View History

package com.mosquito.project.dto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.NullAndEmptySource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* CreateApiKeyResponse DTO测试
*/
@DisplayName("CreateApiKeyResponse DTO测试")
class CreateApiKeyResponseTest {
private ObjectMapper objectMapper;
@BeforeEach
void setUp() {
objectMapper = new ObjectMapper();
}
@Nested
@DisplayName("构造函数测试")
class ConstructorTests {
@Test
@DisplayName("全参数构造函数应该正确设置apiKey字段")
void shouldSetApiKeyCorrectly_WhenUsingAllArgsConstructor() {
// Given
String apiKey = "test-api-key-12345";
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
// Then
assertThat(response.getApiKey()).isEqualTo(apiKey);
}
@Test
@DisplayName("null值构造函数应该正确处理")
void shouldHandleNull_WhenUsingConstructor() {
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(null);
// Then
assertThat(response.getApiKey()).isNull();
}
@Test
@DisplayName("空字符串构造函数应该正确处理")
void shouldHandleEmptyString_WhenUsingConstructor() {
// When
CreateApiKeyResponse response = new CreateApiKeyResponse("");
// Then
assertThat(response.getApiKey()).isEmpty();
}
@Test
@DisplayName("空白字符串构造函数应该正确处理")
void shouldHandleWhitespace_WhenUsingConstructor() {
// Given
String whitespaceKey = " ";
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(whitespaceKey);
// Then
assertThat(response.getApiKey()).isEqualTo(whitespaceKey);
}
@Test
@DisplayName("长字符串构造函数应该正确处理")
void shouldHandleLongString_WhenUsingConstructor() {
// Given
StringBuilder longKey = new StringBuilder();
for (int i = 0; i < 1000; i++) {
longKey.append("key").append(i);
}
String longApiKey = longKey.toString();
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(longApiKey);
// Then
assertThat(response.getApiKey()).isEqualTo(longApiKey);
assertThat(response.getApiKey()).hasSizeGreaterThan(2000);
}
@Test
@DisplayName("特殊字符apiKey构造函数应该正确处理")
void shouldHandleSpecialCharacters_WhenUsingConstructor() {
// Given
String specialKey = "key-🔑-测试!@#$%^&*()_+-=[]{}|;':\",./<>?";
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(specialKey);
// Then
assertThat(response.getApiKey()).isEqualTo(specialKey);
}
@Test
@DisplayName("包含换行符apiKey构造函数应该正确处理")
void shouldHandleNewlines_WhenUsingConstructor() {
// Given
String keyWithNewlines = "line1\nline2\r\nline3\t";
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(keyWithNewlines);
// Then
assertThat(response.getApiKey()).isEqualTo(keyWithNewlines);
}
}
@Nested
@DisplayName("Getter测试")
class GetterTests {
@Test
@DisplayName("getApiKey应该返回正确的值")
void shouldReturnCorrectValue_WhenUsingGetter() {
// Given
String apiKey = "my-secret-api-key";
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
// When
String result = response.getApiKey();
// Then
assertThat(result).isEqualTo(apiKey);
}
@Test
@DisplayName("getApiKey应该返回null当值为null")
void shouldReturnNull_WhenValueIsNull() {
// Given
CreateApiKeyResponse response = new CreateApiKeyResponse(null);
// When
String result = response.getApiKey();
// Then
assertThat(result).isNull();
}
@Test
@DisplayName("getApiKey应该返回空字符串当值为空")
void shouldReturnEmptyString_WhenValueIsEmpty() {
// Given
CreateApiKeyResponse response = new CreateApiKeyResponse("");
// When
String result = response.getApiKey();
// Then
assertThat(result).isEmpty();
}
}
@Nested
@DisplayName("边界值测试")
class BoundaryTests {
@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {" ", "\t", "\n", "\r"})
@DisplayName("边界值apiKey应该正确处理")
void shouldHandleBoundaryValues(String apiKey) {
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
// Then
assertThat(response.getApiKey()).isEqualTo(apiKey);
}
@ParameterizedTest
@ValueSource(strings = {
"a", // 单字符
"AB", // 双字符
"0123456789", // 数字
"abcdefghijklmnopqrstuvwxyz", // 小写字母
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", // 大写字母
"key-with-dashes", // 带横线
"key_with_underscores", // 带下划线
"key.with.dots", // 带点
"key:with:colons", // 带冒号
"key/with/slashes" // 带斜杠
})
@DisplayName("各种格式apiKey应该正确处理")
void shouldHandleVariousFormats(String apiKey) {
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
// Then
assertThat(response.getApiKey()).isEqualTo(apiKey);
}
@Test
@DisplayName("Unicode字符apiKey应该正确处理")
void shouldHandleUnicodeCharacters() {
// Given
String[] unicodeKeys = {
"密钥-中文测试",
"ключ-русский",
"キー-日本語",
"🔑-emoji-test",
"مفتاح-عربي"
};
for (String key : unicodeKeys) {
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(key);
// Then
assertThat(response.getApiKey()).isEqualTo(key);
}
}
@Test
@DisplayName("极大长度apiKey应该正确处理")
void shouldHandleExtremelyLongKey() {
// Given
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append("A");
}
String extremelyLongKey = sb.toString();
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(extremelyLongKey);
// Then
assertThat(response.getApiKey()).hasSize(10000);
assertThat(response.getApiKey()).isEqualTo(extremelyLongKey);
}
@Test
@DisplayName("JSON特殊字符apiKey应该正确处理")
void shouldHandleJsonSpecialCharacters() {
// Given
String jsonSpecialKey = "key{with}[brackets]\"quotes\"'apostrophe'";
// When
CreateApiKeyResponse response = new CreateApiKeyResponse(jsonSpecialKey);
// Then
assertThat(response.getApiKey()).isEqualTo(jsonSpecialKey);
}
}
@Nested
@DisplayName("JSON序列化测试")
class JsonSerializationTests {
@Test
@DisplayName("完整对象应该正确序列化为JSON")
void shouldSerializeCorrectly_CompleteObject() throws JsonProcessingException {
// Given
String apiKey = "test-api-key-12345";
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
// When
String json = objectMapper.writeValueAsString(response);
// Then
assertThat(json).isNotNull();
assertThat(json).contains("\"apiKey\":\"test-api-key-12345\"");
}
@Test
@DisplayName("null值应该正确序列化为JSON")
void shouldSerializeCorrectly_WithNullValue() throws JsonProcessingException {
// Given
CreateApiKeyResponse response = new CreateApiKeyResponse(null);
// When
String json = objectMapper.writeValueAsString(response);
// Then
assertThat(json).isNotNull();
assertThat(json).contains("\"apiKey\":null");
}
@Test
@DisplayName("空字符串应该正确序列化为JSON")
void shouldSerializeCorrectly_WithEmptyString() throws JsonProcessingException {
// Given
CreateApiKeyResponse response = new CreateApiKeyResponse("");
// When
String json = objectMapper.writeValueAsString(response);
// Then
assertThat(json).contains("\"apiKey\":\"\"");
}
@Test
@DisplayName("特殊字符应该正确序列化为JSON")
void shouldSerializeCorrectly_WithSpecialCharacters() throws JsonProcessingException {
// Given
String specialKey = "key-🔑-测试";
CreateApiKeyResponse response = new CreateApiKeyResponse(specialKey);
// When
String json = objectMapper.writeValueAsString(response);
// Then
assertThat(json).isNotNull();
assertThat(json).contains("apiKey");
}
@Test
@DisplayName("JSON转义字符应该正确序列化")
void shouldSerializeCorrectly_WithJsonEscapes() throws JsonProcessingException {
// Given
String keyWithEscapes = "line1\nline2\t\"quoted\"";
CreateApiKeyResponse response = new CreateApiKeyResponse(keyWithEscapes);
// When
String json = objectMapper.writeValueAsString(response);
// Then
assertThat(json).isNotNull();
assertThat(json).contains("apiKey");
}
}
@Nested
@DisplayName("对象行为测试")
class ObjectBehaviorTests {
@Test
@DisplayName("两个相同apiKey的响应应该相等")
void shouldBeEqual_WhenSameApiKey() {
// Given
CreateApiKeyResponse response1 = new CreateApiKeyResponse("same-key");
CreateApiKeyResponse response2 = new CreateApiKeyResponse("same-key");
// Then
assertThat(response1.getApiKey()).isEqualTo(response2.getApiKey());
}
@Test
@DisplayName("两个不同apiKey的响应应该不相等")
void shouldNotBeEqual_WhenDifferentApiKey() {
// Given
CreateApiKeyResponse response1 = new CreateApiKeyResponse("key-1");
CreateApiKeyResponse response2 = new CreateApiKeyResponse("key-2");
// Then
assertThat(response1.getApiKey()).isNotEqualTo(response2.getApiKey());
}
@Test
@DisplayName("多次调用getter应该返回相同值")
void shouldReturnSameValue_WhenCallingGetterMultipleTimes() {
// Given
String apiKey = "consistent-key";
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
// When & Then
assertThat(response.getApiKey()).isEqualTo(apiKey);
assertThat(response.getApiKey()).isEqualTo(apiKey);
assertThat(response.getApiKey()).isEqualTo(apiKey);
}
}
@Nested
@DisplayName("并发安全测试")
class ConcurrencyTests {
@Test
@DisplayName("多线程并发读取应该是安全的")
void shouldBeThreadSafe_ConcurrentReads() throws InterruptedException {
// Given
String apiKey = "concurrent-key";
CreateApiKeyResponse response = new CreateApiKeyResponse(apiKey);
int threadCount = 10;
Thread[] threads = new Thread[threadCount];
boolean[] results = new boolean[threadCount];
// When
for (int i = 0; i < threadCount; i++) {
final int threadIndex = i;
threads[i] = new Thread(() -> {
try {
for (int j = 0; j < 100; j++) {
String value = response.getApiKey();
if (!apiKey.equals(value)) {
results[threadIndex] = false;
return;
}
}
results[threadIndex] = true;
} catch (Exception e) {
results[threadIndex] = false;
}
});
}
// 启动所有线程
for (Thread thread : threads) {
thread.start();
}
// 等待所有线程完成
for (Thread thread : threads) {
thread.join();
}
// Then
for (int i = 0; i < threadCount; i++) {
assertThat(results[i]).isTrue();
}
}
}
}