From 1c47221a45a3fa98b65fabd4d8b4c3522b2bf3a1 Mon Sep 17 00:00:00 2001 From: "ah.jo" Date: Fri, 9 Aug 2024 17:33:19 +0900 Subject: [PATCH] Add customizing interface documentation --- .../docs/customizing-objects/interface.md | 156 ++++++++++++++++++ .../docs/customizing-objects/interface.md | 154 +++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 docs/content/v1.0.x-kor/docs/customizing-objects/interface.md create mode 100644 docs/content/v1.0.x/docs/customizing-objects/interface.md diff --git a/docs/content/v1.0.x-kor/docs/customizing-objects/interface.md b/docs/content/v1.0.x-kor/docs/customizing-objects/interface.md new file mode 100644 index 000000000..5cea9705d --- /dev/null +++ b/docs/content/v1.0.x-kor/docs/customizing-objects/interface.md @@ -0,0 +1,156 @@ +--- +title: "인터페이스 커스터마이징" +weight: 45 +menu: +docs: +parent: "customizing-objects" +identifier: "interface" +--- + +인터페이스에서 `ArbitraryBuilder`의 모든 API를 사용할 수 있습니다. +우리는 이미 [Generating Interface Type](../../generating-objects/generating-interface) 에서 API를 사용한 예를 확인했었습니다. +알아본 내용을 복습하면, 인터페이스의 종류에는 `interface`, `generic interface` ,`selaed interface`이 있습니다. +인터페이스의 종류와 상관없이 모든 인터페이스의 프로퍼티를 제어할 수 있습니다. + +```java +public interface StringSupplier { + String getValue(); +} + +FixtureMonkey fixture = FixtureMonkey.create(); + +String result = fixture.giveMeBuilder(StringSupplier.class) + .set("value", "fix") + .sample() + .getValue(); +``` + +인터페이스를 생성하는 `ArbitraryBuilder`가 제어할 수 있는 프로퍼티는 실제로 생성한 구현체마다 다릅니다. +하지만 아직은 구현체를 선택할 수 있는 `ArbitraryBulder` API가 존재하지 않습니다. +인터페이스가 하나의 구현체를 가지고 있다면 구현체 프로퍼티도 제어가 가능합니다. 하지만 구현체가 두 개 이상이라면 인터페이스의 프로퍼티만 제어가 가능합니다. + + +원하는 구현체를 랜덤하게 생성할 수는 없지만 이미 구현체의 인스턴스가 있다면 원하는 구현체를 `set` API를 사용해 생성할 수 있습니다. +`interfaceImplements 옵션을 사용한 경우`와 `interfaceImplements 옵션을 사용하지 않은 경우` 두 경우로 나누어 설명을 해보겠습니다. + +### 옵션을 사용한 경우 +인터페이스 타입은 `set` API로 설정한 구현체로 생성합니다. 구현체는 `interfaceImplements` 옵션에 등록을 해야 합니다. + +```java +public interface ObjectValueSupplier { + Object getValue(); +} + +public class StringValueSupplier implements ObjectValueSupplier { + private final String value; + + @ConstructorProperties("value") // 롬복을 사용하면 추가하지 않아도 됩니다. + public StringValueSupplier(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } +} + +public class IntegerValueSupplier implements ObjectValueSupplier { + private final int value; + private final int implementationValue; + + @ConstructorProperties({"value", "implementationValue"}) // 롬복을 사용하면 추가하지 않아도 됩니다. + public IntegerValueSupplier(int value, int implementationValue) { + this.value = value; + this.implementationValue = implementationValue; + } + + @Override + public Integer getValue() { + return value; + } + + public int getImplementationValue() { + return implementationValue; + } +} + +FixtureMonkey fixture = FixtureMonkey.builder() + .objectIntrospector( + ConstructorPropertiesArbitraryIntrospector.INSTANCE) // 구현체를 인스턴스화할 때 사용합니다. + .plugin( + new InterfacePlugin() + .interfaceImplements( + ObjectValueSupplier.class, + List.of(StringValueSupplier.class, IntegerValueSupplier.class) + ) + ) + .build(); + +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", new IntegerValueSupplier(-1203)) + .sample(); +``` + +구현체의 프로퍼티도 제어할 수 있습니다. + +```java +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", new IntegerValueSupplier(-1203, 1203)) + .set("implementationValue", 1) // it works. + .sample(); +``` + +### Without the option +원하는 구현체를 설정하기 위해서는 `set` API 를 특별한 방식으로 사용해야 합니다. 구현체 인스턴스를 `Values.just`로 감싸서 입력해야 합니다. + +```java +public interface ObjectValueSupplier { + Object getValue(); +} + +public class StringValueSupplier implements ObjectValueSupplier { + private final String value; + + @ConstructorProperties("value") // 롬복을 사용하면 추가하지 않아도 됩니다. + public StringValueSupplier(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } +} + +public class IntegerValueSupplier implements ObjectValueSupplier { + private final int value; + + @ConstructorProperties("value") // 롬복을 사용하면 추가하지 않아도 됩니다. + public IntegerValueSupplier(int value) { + this.value = value; + } + + @Override + public Integer getValue() { + return value; + } +} + +FixtureMonkey fixture = FixtureMonkey.builder() + .objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE) // 구현체를 인스턴스화할 때 사용합니다. + .build(); + +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", Values.just(new IntegerValueSupplier(-1203))) + .sample(); +``` + +픽스쳐 몽키는 `interfaceImplements` 옵션으로 등록하지 않은 구현체의 프로퍼티를 알 수 없습니다. `Values.just`를 사용한 경우 프로퍼티를 제어할 수 없습니다. + +```java +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", Values.just(new IntegerValueSupplier(-1203))) + .set("value", 1) // not works + .sample(); +``` diff --git a/docs/content/v1.0.x/docs/customizing-objects/interface.md b/docs/content/v1.0.x/docs/customizing-objects/interface.md new file mode 100644 index 000000000..4d3083788 --- /dev/null +++ b/docs/content/v1.0.x/docs/customizing-objects/interface.md @@ -0,0 +1,154 @@ +--- +title: "Customizing Interface" +weight: 45 +menu: +docs: +parent: "customizing-objects" +identifier: "interface" +--- + +The `ArbitraryBuilder` API is also valid within the interface. +You can customize the interface properties regardless of the interface type as said in [Generating Interface Type](../../generating-objects/generating-interface) +The interface type refers to `interface`, `generic interface` ,`selaed interface`. + +```java +public interface StringSupplier { + String getValue(); +} + +FixtureMonkey fixture = FixtureMonkey.create(); + +String result = fixture.giveMeBuilder(StringSupplier.class) + .set("value", "fix") + .sample() + .getValue(); +``` + +The properties of the interface in `ArbitraryBuilder` differ in the implementation. +Unfortunately, there is currently no ArbitraryBuilder API that resolves the implementation of the interface. +Unless the interface has only one implementation, you can customize the properties of the interface, not the implementation. + +You cannot generate the randomly populated intended implementation, but you can generate the fixed implementation by using the `set` API. +There are two cases, `with the interfaceImplements option` and `without the interfaceImplements option`. + +### With the option +The interface type is resolved to the implementation when you use the `set` API with the option. + +```java +public interface ObjectValueSupplier { + Object getValue(); +} + +public class StringValueSupplier implements ObjectValueSupplier { + private final String value; + + @ConstructorProperties("value") // It is not needed if you are using Lombok. + public StringValueSupplier(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } +} + +public class IntegerValueSupplier implements ObjectValueSupplier { + private final int value; + private final int implementationValue; + + @ConstructorProperties({"value", "implementationValue"}) // It is not needed if you are using Lombok. + public IntegerValueSupplier(int value, int implementationValue) { + this.value = value; + this.implementationValue = implementationValue; + } + + @Override + public Integer getValue() { + return value; + } + + public int getImplementationValue() { + return implementationValue; + } +} + +FixtureMonkey fixture = FixtureMonkey.builder() + .objectIntrospector( + ConstructorPropertiesArbitraryIntrospector.INSTANCE) // used for instantiate implementations of ObjectValueSupplier + .plugin( + new InterfacePlugin() + .interfaceImplements( + ObjectValueSupplier.class, + List.of(StringValueSupplier.class, IntegerValueSupplier.class) + ) + ) + .build(); + +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", new IntegerValueSupplier(-1203)) + .sample(); +``` + +You can also change the properties of the implementation. + +```java +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", new IntegerValueSupplier(-1203, 1203)) + .set("implementationValue", 1) // it works. + .sample(); +``` + +### Without the option +You have to use the `set` API in a specific way with `Values.just`. + +```java +public interface ObjectValueSupplier { + Object getValue(); +} + +public class StringValueSupplier implements ObjectValueSupplier { + private final String value; + + @ConstructorProperties("value") // It is not needed if you are using Lombok. + public StringValueSupplier(String value) { + this.value = value; + } + + @Override + public String getValue() { + return value; + } +} + +public class IntegerValueSupplier implements ObjectValueSupplier { + private final int value; + + @ConstructorProperties("value") // It is not needed if you are using Lombok. + public IntegerValueSupplier(int value) { + this.value = value; + } + + @Override + public Integer getValue() { + return value; + } +} + +FixtureMonkey fixture = FixtureMonkey.builder() + .objectIntrospector(ConstructorPropertiesArbitraryIntrospector.INSTANCE) // used for instantiate implementations of ObjectValueSupplier + .build(); + +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", Values.just(new IntegerValueSupplier(-1203))) + .sample(); +``` + +The implementation is not used by `interfaceImplements`, Fixture Monkey does not know the properties of the implementation. You cannot set the properties of the implementation. + +```java +IntegerValueSupplier integerValueSupplier = (IntegerValueSupplier)fixture.giveMeBuilder(ObjectValueSupplier.class) + .set("$", Values.just(new IntegerValueSupplier(-1203))) + .set("value", 1) // not works + .sample(); +```