Skip to content

Commit 07f0ee6

Browse files
authored
support inject S3Client instance to test method parameter. (#84)
1 parent ae9acfa commit 07f0ee6

File tree

8 files changed

+106
-27
lines changed

8 files changed

+106
-27
lines changed

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,14 @@ LocalS3 for Junit5 provides a Java annotation `@LocalS3` helps you easily launch
135135
</dependency>
136136
```
137137

138-
When you annotate it on test classes or test methods, the LocalS3 extension automatically inject instances
139-
for AmazonS3 parameters of test methods.
138+
When you annotate it on test classes or test methods, the LocalS3 extension automatically inject instances with
139+
the following parameter types of test methods.
140+
141+
+ `AmazonS3`
142+
+ `S3Client`
143+
+ `LocalS3Endpoint`
144+
145+
Example 1: Inject a `AmazonS3` object to the test method parameter.
140146

141147
```java
142148
@LocalS3
@@ -146,6 +152,19 @@ class AppTest {
146152
s3.createBucket("my-bucket");
147153
}
148154
}
155+
156+
```
157+
158+
Example 2: Inject a `S3Client` object to the test method parameter
159+
160+
```java
161+
class AppTest {
162+
@Test
163+
@LocalS3
164+
void test(S3Client client) {
165+
client.createBucket(b -> b.bucket("my-bucket"));
166+
}
167+
}
149168
```
150169

151170
#### Difference between `@LocalS3` on test classes and test methods

local-s3-jupiter/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ plugins {
55

66
dependencies {
77
implementation project(":local-s3-rest")
8-
implementation "software.amazon.awssdk:s3:${libVersion['software.amazon.awssdk.s3']}"
9-
implementation "com.amazonaws:aws-java-sdk:${libVersion['com.amazonaws.aws-java-sdk']}"
8+
compileOnly "software.amazon.awssdk:s3:${libVersion['software.amazon.awssdk.s3']}"
9+
compileOnly "com.amazonaws:aws-java-sdk:${libVersion['com.amazonaws.aws-java-sdk']}"
1010
implementation "commons-io:commons-io:${libVersion['commons-io.commons-io']}"
1111
implementation "org.apache.commons:commons-lang3:${libVersion['org.apache.commons.commons-lang3']}"
1212
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${libVersion['com.fasterxml.jackson.dataformat.jackson-dataformat-xml']}"
1313
implementation "org.junit.jupiter:junit-jupiter:${libVersion['org.junit.jupiter.junit-jupiter']}"
1414
testRuntimeOnly "ch.qos.logback:logback-classic:${libVersion['ch.qos.logback.logback-classic']}"
15+
testImplementation "software.amazon.awssdk:s3:${libVersion['software.amazon.awssdk.s3']}"
16+
testImplementation "com.amazonaws:aws-java-sdk:${libVersion['com.amazonaws.aws-java-sdk']}"
1517
}
1618

local-s3-jupiter/src/main/java/com/robothy/s3/jupiter/LocalS3.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,26 @@
44
import com.robothy.s3.jupiter.extensions.AmazonS3Resolver;
55
import com.robothy.s3.jupiter.extensions.LocalS3EndpointResolver;
66
import com.robothy.s3.jupiter.extensions.LocalS3Extension;
7+
import com.robothy.s3.jupiter.extensions.S3ClientResolver;
78
import com.robothy.s3.jupiter.supplier.DataPathSupplier;
89
import com.robothy.s3.rest.bootstrap.LocalS3Mode;
910
import java.lang.annotation.ElementType;
1011
import java.lang.annotation.Retention;
1112
import java.lang.annotation.RetentionPolicy;
1213
import java.lang.annotation.Target;
1314
import org.junit.jupiter.api.extension.ExtendWith;
15+
import software.amazon.awssdk.services.s3.S3Client;
1416

1517
/**
1618
* {@code @LocalS3} is a Junit5/Jupiter extension that runs a mocked AmazonS3 service
1719
* for annotated test classes or test methods. To hit the mocked service, you can add
18-
* {@linkplain AmazonS3} or {@linkplain LocalS3Endpoint} parameters in test methods.
20+
* the following parameter types in test methods.
21+
*
22+
* <ul>
23+
* <li>{@linkplain AmazonS3}</li>
24+
* <li>{@linkplain S3Client}</li>
25+
* <li>{@linkplain LocalS3Endpoint}</li>
26+
* </ul>
1927
*
2028
* <p>Below example injects an {@code AmazonS3} instance to the parameter:
2129
*
@@ -55,6 +63,7 @@
5563
@Retention(RetentionPolicy.RUNTIME)
5664
@ExtendWith(LocalS3Extension.class)
5765
@ExtendWith(AmazonS3Resolver.class)
66+
@ExtendWith(S3ClientResolver.class)
5867
@ExtendWith(LocalS3EndpointResolver.class)
5968
public @interface LocalS3 {
6069

local-s3-jupiter/src/main/java/com/robothy/s3/jupiter/extensions/AbstractLocalS3ParameterResolver.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
import org.junit.jupiter.api.extension.ParameterResolutionException;
66
import org.junit.jupiter.api.extension.ParameterResolver;
77

8-
public abstract class AbstractLocalS3ParameterResolver<T> implements ParameterResolver {
8+
import java.util.Objects;
9+
10+
public abstract class AbstractLocalS3ParameterResolver implements ParameterResolver {
911

1012
@Override
1113
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
1214
throws ParameterResolutionException {
13-
return type() == parameterContext.getParameter().getType();
15+
return Objects.equals(className(), parameterContext.getParameter().getType().getName());
1416
}
1517

1618
@Override
@@ -29,8 +31,8 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte
2931
return resolve(port);
3032
}
3133

32-
protected abstract Class<T> type();
34+
protected abstract String className();
3335

34-
protected abstract T resolve(int port);
36+
protected abstract Object resolve(int port);
3537

3638
}

local-s3-jupiter/src/main/java/com/robothy/s3/jupiter/extensions/AmazonS3Resolver.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,14 @@
22

33
import com.amazonaws.ClientConfiguration;
44
import com.amazonaws.client.builder.AwsClientBuilder;
5-
import com.amazonaws.retry.RetryMode;
6-
import com.amazonaws.retry.RetryPolicy;
75
import com.amazonaws.services.s3.AmazonS3;
86
import com.amazonaws.services.s3.AmazonS3Client;
97
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
10-
import org.junit.jupiter.api.extension.ExtensionContext;
11-
import org.junit.jupiter.api.extension.ParameterContext;
12-
import org.junit.jupiter.api.extension.ParameterResolutionException;
13-
import org.junit.jupiter.api.extension.ParameterResolver;
14-
import org.slf4j.Logger;
15-
import org.slf4j.LoggerFactory;
168

179
/**
1810
* Inject an AmazonS3 instance to a test parameter.
1911
*/
20-
public class AmazonS3Resolver extends AbstractLocalS3ParameterResolver<AmazonS3> {
12+
public class AmazonS3Resolver extends AbstractLocalS3ParameterResolver {
2113

2214
private final AmazonS3ClientBuilder s3Builder = AmazonS3Client.builder()
2315
.enablePathStyleAccess()
@@ -26,8 +18,8 @@ public class AmazonS3Resolver extends AbstractLocalS3ParameterResolver<AmazonS3>
2618
.withSocketTimeout(1000));
2719

2820
@Override
29-
protected Class<AmazonS3> type() {
30-
return AmazonS3.class;
21+
protected String className() {
22+
return "com.amazonaws.services.s3.AmazonS3";
3123
}
3224

3325
@Override

local-s3-jupiter/src/main/java/com/robothy/s3/jupiter/extensions/LocalS3EndpointResolver.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
package com.robothy.s3.jupiter.extensions;
22

33
import com.robothy.s3.jupiter.LocalS3Endpoint;
4-
import org.junit.jupiter.api.extension.ExtensionContext;
5-
import org.junit.jupiter.api.extension.ParameterContext;
6-
import org.junit.jupiter.api.extension.ParameterResolutionException;
7-
import org.junit.jupiter.api.extension.ParameterResolver;
84

9-
public class LocalS3EndpointResolver extends AbstractLocalS3ParameterResolver<LocalS3Endpoint> {
5+
public class LocalS3EndpointResolver extends AbstractLocalS3ParameterResolver {
106

117
@Override
12-
protected Class<LocalS3Endpoint> type() {
13-
return LocalS3Endpoint.class;
8+
protected String className() {
9+
return LocalS3Endpoint.class.getName();
1410
}
1511

1612
@Override
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.robothy.s3.jupiter.extensions;
2+
3+
import lombok.SneakyThrows;
4+
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
5+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
6+
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
7+
import software.amazon.awssdk.regions.Region;
8+
import software.amazon.awssdk.services.s3.S3Client;
9+
10+
import java.net.URI;
11+
12+
public class S3ClientResolver extends AbstractLocalS3ParameterResolver {
13+
14+
@Override
15+
protected String className() {
16+
return "software.amazon.awssdk.services.s3.S3Client";
17+
}
18+
19+
@SneakyThrows
20+
@Override
21+
protected Object resolve(int port) {
22+
String endpoint = "http://localhost:" + port;
23+
24+
return S3Client.builder()
25+
.forcePathStyle(true)
26+
.endpointOverride(new URI(endpoint))
27+
.region(Region.of("local"))
28+
.credentialsProvider(StaticCredentialsProvider.create(
29+
AwsBasicCredentials.create("local-s3-access-key", "local-s3-secret-key")))
30+
.build();
31+
}
32+
33+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.robothy.s3.jupiter.extensions;
2+
3+
import com.robothy.s3.jupiter.LocalS3;
4+
import org.junit.jupiter.api.Test;
5+
import software.amazon.awssdk.core.sync.RequestBody;
6+
import software.amazon.awssdk.services.s3.S3Client;
7+
import software.amazon.awssdk.services.s3.model.CreateBucketResponse;
8+
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
9+
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
10+
11+
import static org.junit.jupiter.api.Assertions.assertNotNull;
12+
13+
@LocalS3
14+
public class S3ClientResolverTest {
15+
16+
@Test
17+
void test(S3Client client){
18+
assertNotNull(client);
19+
CreateBucketResponse createBucketResponse = client.createBucket(b -> b.bucket("my-bucket"));
20+
assertNotNull(createBucketResponse);
21+
PutObjectResponse putObjectResponse = client.putObject(PutObjectRequest.builder()
22+
.bucket("my-bucket").key("a.txt").build(), RequestBody.empty());
23+
assertNotNull(putObjectResponse);
24+
}
25+
26+
}

0 commit comments

Comments
 (0)