Skip to content

Commit a40da1f

Browse files
committed
Improve cheat sheet sections documentation (#1177)
1 parent 5b57910 commit a40da1f

File tree

2 files changed

+622
-40
lines changed
  • docs/content
    • v1.1.x-kor/docs/cheat-sheet
    • v1.1.x/docs/cheat-sheet

2 files changed

+622
-40
lines changed

docs/content/v1.1.x-kor/docs/cheat-sheet/faq.md

Lines changed: 310 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,209 @@ docs:
77
identifier: "faq"
88
---
99

10-
### 생성된 문자열의 문자 범위를 제한하려면 어떻게 해야 할까요?
11-
> 관련 질문 - 생성된 인스턴트 값의 범위를 제한할 수 있나요?
10+
### 픽스쳐 몽키를 어떻게 시작하나요?
1211

13-
일반적으로 픽스처에 제약 조건을 추가하고자 한다면 ArbitraryBuilder와 함께 제공된 Fixture Customization API를 사용할 수 있습니다.
14-
그러나 각 생성된 기본 타입이 특정 제약 조건을 지키길 원하는 경우에는 [`javaTypeArbitaryGenerator``javaTimeTypeArbitraryGenerator`](../../fixture-monkey-options/customization-options/#constraining-java-types)옵션을 사용할 수 있습니다.
12+
픽스쳐 몽키는 랜덤 값을 가진 테스트 객체를 쉽게 생성할 수 있는 방법을 제공합니다. 다음과 같이 시작할 수 있습니다:
1513

16-
`javaTypeArbitaryGenerator` 옵션을 사용하면 문자열 또는 정수와 같은 기본 타입의 초기값을 커스터마이징 할 수 있습니다. 인스턴트와 같은 시간 타입의 경우 `javaTimeTypeArbitaryGenerator` 옵션을 사용할 수 있습니다.
14+
{{< tabpane persist=false >}}
15+
{{< tab header="Java" lang="java">}}
16+
// FixtureMonkey 인스턴스 생성
17+
FixtureMonkey fixtureMonkey = FixtureMonkey.create();
1718

18-
이 옵션은 문자열 생성시 특정 범위의 문자만 사용하려는 경우나 시간 타입을 특정한 범위 내로 생성하려는 경우에 특히 유용합니다.
19+
// 랜덤 객체 생성
20+
Person person = fixtureMonkey.giveMeOne(Person.class);
21+
{{< /tab >}}
22+
{{< tab header="Kotlin" lang="kotlin">}}
23+
// FixtureMonkey 인스턴스 생성
24+
val fixtureMonkey = FixtureMonkey.create()
1925

20-
### 특정 값이 생성되지 않도록 하려면 어떻게 해야 하나요?
21-
[`set()`](../../customizing-objects/apis/#set)을 사용하여 값을 쉽게 지정할 수 있지만, 값을 지정하는 것이 아니라 특정 값이 생성되지 않도록 제외하고 싶은 경우가 있을 수 있습니다.
26+
// 랜덤 객체 생성
27+
val person = fixtureMonkey.giveMeOne<Person>()
28+
{{< /tab >}}
29+
{{< /tabpane>}}
30+
31+
### 픽스쳐 몽키를 프로젝트에 어떻게 추가하나요?
32+
33+
Maven이나 Gradle 프로젝트에 쉽게 픽스쳐 몽키를 추가할 수 있습니다:
34+
35+
{{< tabpane persist=false >}}
36+
{{< tab header="Gradle (Kotlin)" lang="kotlin">}}
37+
implementation("com.navercorp.fixturemonkey:fixture-monkey:1.1.x")
38+
{{< /tab >}}
39+
{{< tab header="Gradle (Groovy)" lang="groovy">}}
40+
implementation 'com.navercorp.fixturemonkey:fixture-monkey:1.1.x'
41+
{{< /tab >}}
42+
{{< tab header="Maven" lang="xml">}}
43+
<dependency>
44+
<groupId>com.navercorp.fixturemonkey</groupId>
45+
<artifactId>fixture-monkey</artifactId>
46+
<version>1.1.x</version>
47+
</dependency>
48+
{{< /tab >}}
49+
{{< /tabpane>}}
50+
51+
### 특정 필드만 값을 지정하고 나머지는 랜덤으로 생성하려면 어떻게 하나요?
52+
53+
`set()` 메서드를 사용하여 특정 필드의 값을 지정할 수 있습니다:
54+
55+
{{< tabpane persist=false >}}
56+
{{< tab header="Java" lang="java">}}
57+
Person person = fixtureMonkey.giveMeBuilder(Person.class)
58+
.set("name", "홍길동")
59+
.set("age", 25)
60+
.sample();
61+
{{< /tab >}}
62+
{{< tab header="Kotlin" lang="kotlin">}}
63+
val person = fixtureMonkey.giveMeBuilder<Person>()
64+
.setExpGetter(Person::getName, "홍길동")
65+
.setExpGetter(Person::getAge, 25)
66+
.sample()
67+
{{< /tab >}}
68+
{{< /tabpane>}}
69+
70+
### List, Set, Map 같은 컬렉션의 크기를 어떻게 제어하나요?
71+
72+
`size()` 메서드를 사용하여 컬렉션의 크기를 제어할 수 있습니다:
73+
74+
{{< tabpane persist=false >}}
75+
{{< tab header="Java" lang="java">}}
76+
Person person = fixtureMonkey.giveMeBuilder(Person.class)
77+
.size("friends", 5) // friends 리스트의 크기를 5로 설정
78+
.sample();
79+
80+
// 크기 범위 설정
81+
Product product = fixtureMonkey.giveMeBuilder(Product.class)
82+
.size("tags", 2, 5) // tags 리스트의 크기가 2~5개가 됨
83+
.sample();
84+
{{< /tab >}}
85+
{{< tab header="Kotlin" lang="kotlin">}}
86+
val person = fixtureMonkey.giveMeBuilder<Person>()
87+
.setExpSize(Person::getFriends, 5) // friends 리스트의 크기를 5로 설정
88+
.sample()
89+
90+
// 크기 범위 설정
91+
val product = fixtureMonkey.giveMeBuilder<Product>()
92+
.setExpSize(Product::getTags, 2, 5) // tags 리스트의 크기가 2~5개가 됨
93+
.sample()
94+
{{< /tab >}}
95+
{{< /tabpane>}}
96+
97+
### null 값은 어떻게 처리하나요?
2298

23-
예를 들어, 클래스에 Enum 타입의 필드가 있고 그 필드가 특정 값을 갖지 않게 하려면, 아래와 같이 [`set()`](.../.../customizing-objects/apis/#set)를 사용할 수 있습니다.
99+
`nullInject` 옵션을 사용하여 null 확률을 제어할 수 있습니다:
100+
101+
{{< tabpane persist=false >}}
102+
{{< tab header="Java" lang="java">}}
103+
// null 값이 없는 FixtureMonkey 생성
104+
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
105+
.nullInject(0.0) // null 확률을 0으로 설정
106+
.build();
107+
108+
// null 확률이 50%인 FixtureMonkey 생성
109+
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
110+
.nullInject(0.5) // null 확률을 50%로 설정
111+
.build();
112+
113+
// 특정 필드를 null로 설정
114+
Person person = fixtureMonkey.giveMeBuilder(Person.class)
115+
.set("address", null)
116+
.sample();
117+
{{< /tab >}}
118+
{{< tab header="Kotlin" lang="kotlin">}}
119+
// null 값이 없는 FixtureMonkey 생성
120+
val fixtureMonkey = FixtureMonkey.builder()
121+
.nullInject(0.0) // null 확률을 0으로 설정
122+
.build()
123+
124+
// null 확률이 50%인 FixtureMonkey 생성
125+
val fixtureMonkey = FixtureMonkey.builder()
126+
.nullInject(0.5) // null 확률을 50%로 설정
127+
.build()
128+
129+
// 특정 필드를 null로 설정
130+
val person = fixtureMonkey.giveMeBuilder<Person>()
131+
.setExpGetter(Person::getAddress, null)
132+
.sample()
133+
{{< /tab >}}
134+
{{< /tabpane>}}
135+
136+
### 테스트를 재현 가능하게 만들려면 어떻게 해야 하나요?
137+
138+
고정된 시드를 사용하여 테스트 실행 간에 동일한 데이터를 생성할 수 있습니다:
139+
140+
{{< tabpane persist=false >}}
141+
{{< tab header="Java" lang="java">}}
142+
// 고정된 시드로 FixtureMonkey 생성
143+
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
144+
.seed(123L)
145+
.build();
146+
{{< /tab >}}
147+
{{< tab header="Kotlin" lang="kotlin">}}
148+
// 고정된 시드로 FixtureMonkey 생성
149+
val fixtureMonkey = FixtureMonkey.builder()
150+
.seed(123L)
151+
.build()
152+
{{< /tab >}}
153+
{{< /tabpane>}}
154+
155+
JUnit에서는 `@Seed` 어노테이션을 사용할 수도 있습니다:
156+
157+
{{< tabpane persist=false >}}
158+
{{< tab header="Java" lang="java">}}
159+
@Test
160+
@Seed(123L)
161+
void testWithSeed() {
162+
Person person = fixtureMonkey.giveMeOne(Person.class);
163+
// 매번 동일한 Person이 생성됨
164+
}
165+
{{< /tab >}}
166+
{{< tab header="Kotlin" lang="kotlin">}}
167+
@Test
168+
@Seed(123L)
169+
fun testWithSeed() {
170+
val person = fixtureMonkey.giveMeOne<Person>()
171+
// 매번 동일한 Person이 생성됨
172+
}
173+
{{< /tab >}}
174+
{{< /tabpane>}}
175+
176+
### 생성된 객체가 특정 조건을 만족하도록 하려면 어떻게 해야 하나요?
177+
178+
`setPostCondition()`을 사용하여 조건을 만족하지 않는 생성된 객체를 필터링할 수 있습니다:
179+
180+
{{< tabpane persist=false >}}
181+
{{< tab header="Java" lang="java">}}
182+
// 성인만 생성되도록 함
183+
Person adult = fixtureMonkey.giveMeBuilder(Person.class)
184+
.setPostCondition(person -> person.getAge() >= 18)
185+
.sample();
186+
187+
// 특정 필드가 조건을 만족하도록 함
188+
Product product = fixtureMonkey.giveMeBuilder(Product.class)
189+
.setPostCondition("price", Double.class, price -> price > 0 && price < 1000)
190+
.sample();
191+
{{< /tab >}}
192+
{{< tab header="Kotlin" lang="kotlin">}}
193+
// 성인만 생성되도록 함
194+
val adult = fixtureMonkey.giveMeBuilder<Person>()
195+
.setPostCondition { it.age >= 18 }
196+
.sample()
197+
198+
// 특정 필드가 조건을 만족하도록 함
199+
val product = fixtureMonkey.giveMeBuilder<Product>()
200+
.setPostConditionExpGetter(Product::getPrice, Double::class.java) { it > 0 && it < 1000 }
201+
.sample()
202+
{{< /tab >}}
203+
{{< /tabpane>}}
204+
205+
### 특정 값이 생성되지 않도록 하려면 어떻게 해야 하나요?
206+
필터를 사용하여 `set()`으로 특정 값을 제외할 수 있습니다:
24207

25208
{{< tabpane persist=false >}}
26209
{{< tab header="Java" lang="java">}}
27210

28211
Product product = sut.giveMeBuilder(Product.class)
29-
.set("productType", ArbitraryUtils.toCombinableArbitrary(Arbitraries.of(ProductType)).filter(it -> it != CLOTHING && it != ELECTRONICS)))
212+
.set("productType", ArbitraryUtils.toCombinableArbitrary(Arbitraries.of(ProductType)).filter(it -> it != CLOTHING && it != ELECTRONICS))
30213
.sample();
31214

32215
{{< /tab >}}
@@ -39,38 +222,147 @@ val product = sut.giveMeBuilder<Product>()
39222
{{< /tab >}}
40223
{{< /tabpane>}}
41224

42-
혹은 일종의 필터처럼 동작하는 [`setPostCondition()`](../../customizing-objects/apis/#setpostcondition)을 사용할 수 있습니다.
225+
또는 필터처럼 동작하는 `setPostCondition()`을 사용할 수 있습니다:
43226

44227
{{< tabpane persist=false >}}
45228
{{< tab header="Java" lang="java">}}
46229

47230
Product product = sut.giveMeBuilder(Product.class)
48-
.setPostCondition("productType", ProductType.class, it -> it != CLOTHING || it != ELECTRONICS)
231+
.setPostCondition("productType", ProductType.class, it -> it != CLOTHING && it != ELECTRONICS)
49232
.sample();
50233

51234
{{< /tab >}}
52235
{{< tab header="Kotlin" lang="kotlin">}}
53236

54237
val product = sut.giveMeBuilder<Product>()
55-
.setPostConditionExpGetter(Product::getProductType, ProductType::class.java) { it != ProductType.CLOTHING || it != ProductType.ELECTRONICS }
238+
.setPostConditionExpGetter(Product::getProductType, ProductType::class.java) { it != ProductType.CLOTHING && it != ProductType.ELECTRONICS }
56239
.sample()
57240

58241
{{< /tab >}}
59242
{{< /tabpane>}}
60243

61244
`setPostCondition()`을 사용하면 Product 인스턴스가 생성된 후 필터링되므로 제한적인 조건에서 더 높은 비용이 발생할 수 있습니다. 이러한 경우 `set()`을 대신 사용하는 것이 권장됩니다.
62245

246+
### 중첩된 객체는 어떻게 처리하나요?
247+
248+
픽스쳐 몽키는 중첩된 객체를 자동으로 생성합니다. 속성 경로를 사용하여 이러한 객체를 커스터마이징할 수 있습니다:
249+
250+
{{< tabpane persist=false >}}
251+
{{< tab header="Java" lang="java">}}
252+
Order order = fixtureMonkey.giveMeBuilder(Order.class)
253+
.set("customer.name", "홍길동")
254+
.set("customer.address.city", "서울")
255+
.size("items", 3)
256+
.set("items[0].productName", "노트북")
257+
.sample();
258+
{{< /tab >}}
259+
{{< tab header="Kotlin" lang="kotlin">}}
260+
val order = fixtureMonkey.giveMeBuilder<Order>()
261+
.setExp("customer.name", "홍길동")
262+
.setExp("customer.address.city", "서울")
263+
.sizeExp("items", 3)
264+
.setExp("items[0].productName", "노트북")
265+
.sample()
266+
{{< /tab >}}
267+
{{< /tabpane>}}
268+
63269
### 필드 중 하나가 다른 필드의 값에 의존하고 있습니다. 이러한 픽스처를 커스터마이징 하려면 어떻게 해야 하나요?
64270

65-
`thenApply()` 메서드는 다른 필드에 의존하는 필드를 커스터마이징 할 때 유용합니다. 자세한 내용은 [`thenApply()`](../../customizing-objects/apis/#thenapply)을 확인해주세요.
271+
`thenApply()` 메서드는 다른 필드에 의존하는 필드를 커스터마이징 할 때 유용합니다:
272+
273+
{{< tabpane persist=false >}}
274+
{{< tab header="Java" lang="java">}}
275+
Money money = fixtureMonkey.giveMeBuilder(Money.class)
276+
.set("currency", Currency.getInstance("KRW"))
277+
.thenApply((m, builder) ->
278+
builder.set("amount", m.getCurrency().equals(Currency.getInstance("KRW")) ? 10000.0 : 100.0))
279+
.sample();
280+
{{< /tab >}}
281+
{{< tab header="Kotlin" lang="kotlin">}}
282+
val money = fixtureMonkey.giveMeBuilder<Money>()
283+
.setExpGetter(Money::getCurrency, Currency.getInstance("KRW"))
284+
.thenApply { money, builder ->
285+
builder.setExpGetter(Money::getAmount, if (money.currency == Currency.getInstance("KRW")) 10000.0 else 100.0)
286+
}
287+
.sample()
288+
{{< /tab >}}
289+
{{< /tabpane>}}
290+
291+
자세한 내용은 [`thenApply()`](../../customizing-objects/apis/#thenapply)를 확인해주세요.
292+
293+
### 생성된 문자열의 문자 범위를 제한하려면 어떻게 해야 할까요?
294+
> 관련 질문 - 생성된 인스턴트 값의 범위를 제한할 수 있나요?
295+
296+
각 생성된 기본 타입이 특정 제약 조건을 지키길 원하는 경우에는 [`javaTypeArbitaryGenerator``javaTimeTypeArbitraryGenerator`](../../fixture-monkey-options/customization-options/#constraining-java-types) 옵션을 사용할 수 있습니다.
297+
298+
{{< tabpane persist=false >}}
299+
{{< tab header="Java" lang="java">}}
300+
// 특정 문자 범위로 문자열 생성 설정
301+
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
302+
.javaTypeArbitraryGenerator(new JavaTypeArbitraryGenerator() {
303+
@Override
304+
public StringArbitrary strings() {
305+
return Arbitraries.strings().alpha().ofLength(5, 10);
306+
}
307+
})
308+
.build();
309+
310+
// 특정 범위로 시간 생성 설정
311+
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
312+
.javaTimeTypeArbitraryGenerator(new JavaTimeTypeArbitraryGenerator() {
313+
@Override
314+
public Arbitrary<Instant> instant() {
315+
Instant start = Instant.parse("2023-01-01T00:00:00Z");
316+
Instant end = Instant.parse("2023-12-31T23:59:59Z");
317+
return Arbitraries.instants().between(start, end);
318+
}
319+
})
320+
.build();
321+
{{< /tab >}}
322+
{{< tab header="Kotlin" lang="kotlin">}}
323+
// 특정 문자 범위로 문자열 생성 설정
324+
val fixtureMonkey = FixtureMonkey.builder()
325+
.javaTypeArbitraryGenerator(object : JavaTypeArbitraryGenerator() {
326+
override fun strings(): StringArbitrary {
327+
return Arbitraries.strings().alpha().ofLength(5, 10)
328+
}
329+
})
330+
.build()
331+
332+
// 특정 범위로 시간 생성 설정
333+
val fixtureMonkey = FixtureMonkey.builder()
334+
.javaTimeTypeArbitraryGenerator(object : JavaTimeTypeArbitraryGenerator() {
335+
override fun instant(): Arbitrary<Instant> {
336+
val start = Instant.parse("2023-01-01T00:00:00Z")
337+
val end = Instant.parse("2023-12-31T23:59:59Z")
338+
return Arbitraries.instants().between(start, end)
339+
}
340+
})
341+
.build()
342+
{{< /tab >}}
343+
{{< /tabpane>}}
66344

67345
### 특정 타입을 생성할 때 예외가 발생해요
68346

69-
먼저 [PriorityConstructorArbitraryIntrospector](../../generating-objects/introspector/#PriorityConstructorArbitraryIntrospector)를 사용해보세요. 다음과 같이 사용할 수 있습니다.
70-
```java
71-
FixtureMonkey.builder()
347+
특정 타입을 생성할 때 예외가 발생하면 [PriorityConstructorArbitraryIntrospector](../../generating-objects/introspector/#PriorityConstructorArbitraryIntrospector)를 시도해보세요:
348+
349+
{{< tabpane persist=false >}}
350+
{{< tab header="Java" lang="java">}}
351+
FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
72352
.pushExactTypeArbitraryIntrospector(ProblematicType.class, PriorityConstructorArbitraryIntrospector.INSTANCE)
73353
.build();
74-
```
354+
355+
// 이제 생성이 잘 될 것입니다
356+
ProblematicType instance = fixtureMonkey.giveMeOne(ProblematicType.class);
357+
{{< /tab >}}
358+
{{< tab header="Kotlin" lang="kotlin">}}
359+
val fixtureMonkey = FixtureMonkey.builder()
360+
.pushExactTypeArbitraryIntrospector(ProblematicType::class.java, PriorityConstructorArbitraryIntrospector.INSTANCE)
361+
.build()
362+
363+
// 이제 생성이 잘 될 것입니다
364+
val instance = fixtureMonkey.giveMeOne<ProblematicType>()
365+
{{< /tab >}}
366+
{{< /tabpane>}}
75367

76368
위 옵션을 추가했는데도 동작하지 않는다면, `ArbitraryIntrospector`을 직접 만들거나 깃허브에 [이슈](https://github.com/naver/fixture-monkey/issues)를 만들어주시면 도움을 드리겠습니다.

0 commit comments

Comments
 (0)