Skip to content

Commit 9ed5ea3

Browse files
committed
Release 1.1.12 version
1 parent 53146d9 commit 9ed5ea3

9 files changed

Lines changed: 695 additions & 8 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ Add Fixture Monkey to your project:
3434

3535
```groovy
3636
// Java
37-
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter:1.1.11")
37+
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter:1.1.12")
3838
3939
// Kotlin
40-
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter-kotlin:1.1.11")
40+
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter-kotlin:1.1.12")
4141
```
4242

4343
### Maven
@@ -47,15 +47,15 @@ testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter-kotlin:1.
4747
<dependency>
4848
<groupId>com.navercorp.fixturemonkey</groupId>
4949
<artifactId>fixture-monkey-starter</artifactId>
50-
<version>1.1.11</version>
50+
<version>1.1.12</version>
5151
<scope>test</scope>
5252
</dependency>
5353

5454
<!-- Kotlin -->
5555
<dependency>
5656
<groupId>com.navercorp.fixturemonkey</groupId>
5757
<artifactId>fixture-monkey-starter-kotlin</artifactId>
58-
<version>1.1.11</version>
58+
<version>1.1.12</version>
5959
<scope>test</scope>
6060
</dependency>
6161
```

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77

88
allprojects {
99
group = "com.navercorp.fixturemonkey"
10-
version = "1.1.12-SNAPSHOT"
10+
version = "1.1.12"
1111
}
1212

1313
subprojects {

docs/config/_default/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,4 @@ rel = "sitemap"
112112
target = "layouts"
113113

114114
[params]
115-
version = "1.1.11"
115+
version = "1.1.12"

docs/config/_default/params.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description = ""
88

99
## Documentation
1010
docsVersion = "1.0.0"
11-
fixtureMonkeyVersion = "1.1.11"
11+
fixtureMonkeyVersion = "1.1.12"
1212

1313
## Open Graph
1414
images = ["fixtureMonkey.png"]
@@ -115,4 +115,4 @@ lastMod = false
115115
collapsibleSidebar = true
116116

117117
[[params.versions]]
118-
version = "1.1.11"
118+
version = "1.1.12"

docs/content/v1.1.x-kor/docs/customizing-objects/arbitrary.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,207 @@ Test Method [MembershipTest#성인_회원만_가능한_테스트] failed with se
230230

231231
생성된 값에 대한 더 많은 제어가 필요하거나, `setPostCondition()`이 많은 유효하지 않은 값을 폐기해야 해서 너무 느릴 때는 `Arbitrary`를 사용하세요.
232232

233+
## 고급 Arbitrary 타입 (실험적 기능)
234+
235+
버전 1.1.12부터 Fixture Monkey는 값 생성을 더 세밀하게 제어할 수 있는 전용 arbitrary 타입을 제공합니다.
236+
237+
### CombinableArbitrary.integers()
238+
239+
`CombinableArbitrary.integers()` 메서드는 정수 생성을 위한 전용 메서드들을 제공하는 `IntegerCombinableArbitrary`를 반환합니다:
240+
241+
{{< tabpane persist=false >}}
242+
{{< tab header="Java" lang="java">}}
243+
// 다양한 제약조건을 가진 정수 생성
244+
Member member = fixtureMonkey.giveMeBuilder(Member.class)
245+
.set("age", CombinableArbitrary.integers()
246+
.withRange(18, 65) // 18-65세 사이
247+
.positive()) // 양수만
248+
.set("score", CombinableArbitrary.integers()
249+
.even() // 짝수만
250+
.withRange(0, 100)) // 0-100 사이
251+
.sample();
252+
{{< /tab >}}
253+
{{< tab header="Kotlin" lang="kotlin">}}
254+
// 다양한 제약조건을 가진 정수 생성
255+
val member = fixtureMonkey.giveMeBuilder<Member>()
256+
.setExp(Member::age, CombinableArbitrary.integers()
257+
.withRange(18, 65) // 18-65세 사이
258+
.positive()) // 양수만
259+
.setExp(Member::score, CombinableArbitrary.integers()
260+
.even() // 짝수만
261+
.withRange(0, 100)) // 0-100 사이
262+
.sample()
263+
{{< /tab >}}
264+
{{< /tabpane>}}
265+
266+
#### IntegerCombinableArbitrary 메서드
267+
268+
| 메서드 | 설명 | 예시 |
269+
|--------|------|------|
270+
| `withRange(min, max)` | min과 max 사이의 정수 생성 (양 끝값 포함) | `integers().withRange(1, 100)` |
271+
| `positive()` | 양수만 생성 (≥ 1) | `integers().positive()` |
272+
| `negative()` | 음수만 생성 (≤ -1) | `integers().negative()` |
273+
| `even()` | 짝수만 생성 | `integers().even()` |
274+
| `odd()` | 홀수만 생성 | `integers().odd()` |
275+
276+
**중요 참고사항:** 여러 제약조건 메서드를 연결할 때 **마지막 메서드가 우선**됩니다. 예를 들어:
277+
```java
278+
// positive() 호출을 무시하고 음수를 생성합니다
279+
CombinableArbitrary.integers().positive().negative()
280+
281+
// positive() 호출을 무시하고 10-50 범위의 정수를 생성합니다
282+
CombinableArbitrary.integers().positive().withRange(10, 50)
283+
```
284+
285+
### CombinableArbitrary.strings()
286+
287+
`CombinableArbitrary.strings()` 메서드는 문자열 생성을 위한 전용 메서드들을 제공하는 `StringCombinableArbitrary`를 반환합니다:
288+
289+
{{< tabpane persist=false >}}
290+
{{< tab header="Java" lang="java">}}
291+
// 다양한 문자 집합과 제약조건을 가진 문자열 생성
292+
User user = fixtureMonkey.giveMeBuilder(User.class)
293+
.set("username", CombinableArbitrary.strings()
294+
.alphabetic() // 알파벳 문자만
295+
.withLength(5, 15)) // 길이 5-15
296+
.set("password", CombinableArbitrary.strings()
297+
.ascii() // ASCII 문자
298+
.withMinLength(8)) // 최소 8자
299+
.set("phoneNumber", CombinableArbitrary.strings()
300+
.numeric() // 숫자 문자만
301+
.withLength(10, 11)) // 10자리 또는 11자리
302+
.sample();
303+
{{< /tab >}}
304+
{{< tab header="Kotlin" lang="kotlin">}}
305+
// 다양한 문자 집합과 제약조건을 가진 문자열 생성
306+
val user = fixtureMonkey.giveMeBuilder<User>()
307+
.setExp(User::username, CombinableArbitrary.strings()
308+
.alphabetic() // 알파벳 문자만
309+
.withLength(5, 15)) // 길이 5-15
310+
.setExp(User::password, CombinableArbitrary.strings()
311+
.ascii() // ASCII 문자
312+
.withMinLength(8)) // 최소 8자
313+
.setExp(User::phoneNumber, CombinableArbitrary.strings()
314+
.numeric() // 숫자 문자만
315+
.withLength(10, 11)) // 10자리 또는 11자리
316+
.sample()
317+
{{< /tab >}}
318+
{{< /tabpane>}}
319+
320+
#### StringCombinableArbitrary 메서드
321+
322+
| 메서드 | 설명 | 예시 |
323+
|--------|------|------|
324+
| `withLength(min, max)` | min과 max 사이 길이의 문자열 생성 | `strings().withLength(5, 10)` |
325+
| `withMinLength(min)` | 최소 길이를 가진 문자열 생성 | `strings().withMinLength(3)` |
326+
| `withMaxLength(max)` | 최대 길이를 가진 문자열 생성 | `strings().withMaxLength(20)` |
327+
| `alphabetic()` | 알파벳 문자만 포함하는 문자열 생성 (a-z, A-Z) | `strings().alphabetic()` |
328+
| `ascii()` | ASCII 문자만 포함하는 문자열 생성 | `strings().ascii()` |
329+
| `numeric()` | 숫자 문자만 포함하는 문자열 생성 (0-9) | `strings().numeric()` |
330+
| `korean()` | 한글 문자만 포함하는 문자열 생성 (가-힣) | `strings().korean()` |
331+
| `filterCharacter(predicate)` | 문자열의 개별 문자를 필터링 | `strings().filterCharacter(c -> c != 'x')` |
332+
333+
**중요 참고사항:**
334+
1. **문자 집합 메서드들은 서로 충돌합니다.** 여러 문자 집합 메서드를 연결할 때 **마지막 메서드가 우선**됩니다:
335+
```java
336+
// alphabetic()을 무시하고 한글 문자만 생성합니다
337+
CombinableArbitrary.strings().alphabetic().korean()
338+
```
339+
340+
2. **문자 집합 메서드는 다른 설정 메서드를 무시합니다.** 문자 집합 메서드가 호출되면 이전 설정을 무시하는 새 인스턴스가 생성됩니다:
341+
```java
342+
// alphabetic()이 호출되면 withLength(5, 10)이 무시됩니다
343+
CombinableArbitrary.strings().withLength(5, 10).alphabetic()
344+
```
345+
346+
### 고급 필터링
347+
348+
`IntegerCombinableArbitrary``StringCombinableArbitrary` 모두 고급 필터링을 지원합니다:
349+
350+
{{< tabpane persist=false >}}
351+
{{< tab header="Java" lang="java">}}
352+
// 사용자 정의 조건으로 정수 필터링
353+
Integer score = CombinableArbitrary.integers()
354+
.withRange(0, 100)
355+
.filter(n -> n % 5 == 0) // 5의 배수만
356+
.combined();
357+
358+
// 사용자 정의 문자 조건으로 문자열 필터링
359+
String code = CombinableArbitrary.strings()
360+
.withLength(6, 8)
361+
.filterCharacter(c -> Character.isUpperCase(c) || Character.isDigit(c)) // 대문자와 숫자만
362+
.combined();
363+
{{< /tab >}}
364+
{{< tab header="Kotlin" lang="kotlin">}}
365+
// 사용자 정의 조건으로 정수 필터링
366+
val score = CombinableArbitrary.integers()
367+
.withRange(0, 100)
368+
.filter { it % 5 == 0 } // 5의 배수만
369+
.combined()
370+
371+
// 사용자 정의 문자 조건으로 문자열 필터링
372+
val code = CombinableArbitrary.strings()
373+
.withLength(6, 8)
374+
.filterCharacter { it.isUpperCase() || it.isDigit() } // 대문자와 숫자만
375+
.combined()
376+
{{< /tab >}}
377+
{{< /tabpane>}}
378+
379+
### 실제 사례: 사용자 등록 검증
380+
381+
{{< tabpane persist=false >}}
382+
{{< tab header="Java" lang="java">}}
383+
@Test
384+
void 다양한_입력으로_사용자_등록_검증() {
385+
for (int i = 0; i < 100; i++) {
386+
User user = fixtureMonkey.giveMeBuilder(User.class)
387+
.set("username", CombinableArbitrary.strings()
388+
.alphabetic()
389+
.withLength(3, 20)) // 유효한 사용자명: 3-20자 알파벳
390+
.set("email", CombinableArbitrary.strings()
391+
.ascii()
392+
.withLength(5, 50)
393+
.filter(s -> s.contains("@"))) // 간단한 이메일 검증
394+
.set("age", CombinableArbitrary.integers()
395+
.withRange(13, 120)) // 유효한 나이 범위
396+
.set("score", CombinableArbitrary.integers()
397+
.withRange(0, 100)
398+
.filter(n -> n % 10 == 0)) // 10의 배수인 점수
399+
.sample();
400+
401+
// 다양한 유효한 입력으로 테스트
402+
ValidationResult result = userService.validateRegistration(user);
403+
assertThat(result.isValid()).isTrue();
404+
}
405+
}
406+
{{< /tab >}}
407+
{{< tab header="Kotlin" lang="kotlin">}}
408+
@Test
409+
fun 다양한_입력으로_사용자_등록_검증() {
410+
repeat(100) {
411+
val user = fixtureMonkey.giveMeBuilder<User>()
412+
.setExp(User::username, CombinableArbitrary.strings()
413+
.alphabetic()
414+
.withLength(3, 20)) // 유효한 사용자명: 3-20자 알파벳
415+
.setExp(User::email, CombinableArbitrary.strings()
416+
.ascii()
417+
.withLength(5, 50)
418+
.filter { it.contains("@") }) // 간단한 이메일 검증
419+
.setExp(User::age, CombinableArbitrary.integers()
420+
.withRange(13, 120)) // 유효한 나이 범위
421+
.setExp(User::score, CombinableArbitrary.integers()
422+
.withRange(0, 100)
423+
.filter { it % 10 == 0 }) // 10의 배수인 점수
424+
.sample()
425+
426+
// 다양한 유효한 입력으로 테스트
427+
val result = userService.validateRegistration(user)
428+
assertThat(result.isValid).isTrue()
429+
}
430+
}
431+
{{< /tab >}}
432+
{{< /tabpane>}}
433+
233434
## 추가 자료
234435

235436
모든 Arbitrary 유형과 메서드에 대한 자세한 내용은 [Jqwik 사용자 가이드](https://jqwik.net/docs/current/user-guide.html#static-arbitraries-methods)를 참조하세요.

0 commit comments

Comments
 (0)