Skip to content

Commit

Permalink
[mock] verifyTimes with RequestKey parameter (#1517)
Browse files Browse the repository at this point in the history
* [mock] verifyTimes with RequestKey parameter

* Re-implement verify* methods with RequestKey parameters and stricter equals check for headers and body

Co-authored-by: Marvin Froeder <velo@users.noreply.github.com>
  • Loading branch information
vitalijr2 and velo committed Oct 14, 2021
1 parent f66d888 commit 2cb3fca
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 11 deletions.
44 changes: 43 additions & 1 deletion mock/src/main/java/feign/mock/MockClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2012-2020 The Feign Authors
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand Down Expand Up @@ -222,6 +222,10 @@ public Request verifyOne(HttpMethod method, String url) {
return verifyTimes(method, url, 1).get(0);
}

public Request verifyOne(RequestKey requestKey) {
return verifyTimes(requestKey, 1).get(0);
}

public List<Request> verifyTimes(final HttpMethod method, final String url, final int times) {
if (times < 0) {
throw new IllegalArgumentException("times must be a non negative number");
Expand All @@ -248,13 +252,51 @@ public List<Request> verifyTimes(final HttpMethod method, final String url, fina
return result;
}

public List<Request> verifyTimes(RequestKey requestKey, final int times) {
if (times < 0) {
throw new IllegalArgumentException("times must be a non negative number");
}

if (times == 0) {
verifyNever(requestKey);
return Collections.emptyList();
}

List<Request> result = null;
for (Map.Entry<RequestKey, List<Request>> request : requests.entrySet()) {
if (request.getKey().equalsExtended(requestKey)) {
result = request.getValue();
}
}
if (result == null) {
throw new VerificationAssertionError("Wanted: '%s' but never invoked! Got: %s", requestKey,
requests.keySet());
}

if (result.size() != times) {
throw new VerificationAssertionError("Wanted: '%s' to be invoked: '%s' times but got: '%s'!",
requestKey,
times, result.size());
}

return result;
}

public void verifyNever(HttpMethod method, String url) {
RequestKey requestKey = RequestKey.builder(method, url).build();
if (requests.containsKey(requestKey)) {
throw new VerificationAssertionError("Do not wanted: '%s' but was invoked!", requestKey);
}
}

public void verifyNever(RequestKey requestKey) {
for (RequestKey recorderRequestKey : requests.keySet()) {
if (recorderRequestKey.equalsExtended(requestKey)) {
throw new VerificationAssertionError("Do not wanted: '%s' but was invoked!", requestKey);
}
}
}

/**
* To be called in an &#64;After method:
*
Expand Down
79 changes: 69 additions & 10 deletions mock/src/test/java/feign/mock/MockClientTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2012-2020 The Feign Authors
* Copyright 2012-2021 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand All @@ -13,6 +13,7 @@
*/
package feign.mock;

import static feign.Util.UTF_8;
import static feign.Util.toByteArray;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
Expand All @@ -26,16 +27,10 @@
import java.lang.reflect.Type;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import feign.*;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import feign.Body;
import feign.Feign;
import feign.FeignException;
import feign.Param;
import feign.Request;
import feign.RequestLine;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import feign.gson.GsonDecoder;
Expand All @@ -56,6 +51,7 @@ List<Contributor> contributors(@Param("client_id") String clientId,
List<Contributor> patchContributors(@Param("owner") String owner, @Param("repo") String repo);

@RequestLine("POST /repos/{owner}/{repo}/contributors")
@Headers({"Content-Type: application/json"})
@Body("%7B\"login\":\"{login}\",\"type\":\"{type}\"%7D")
Contributor create(@Param("owner") String owner,
@Param("repo") String repo,
Expand Down Expand Up @@ -97,14 +93,22 @@ public Object decode(Response response, Type type)
public void setup() throws IOException {
try (InputStream input = getClass().getResourceAsStream("/fixtures/contributors.json")) {
byte[] data = toByteArray(input);
RequestKey postContributorKey =
RequestKey.builder(HttpMethod.POST, "/repos/netflix/feign/contributors")
.charset(UTF_8)
.headers(RequestHeaders.builder()
.add("Content-Length", "55")
.add("Content-Type", "application/json")
.build())
.body("{\"login\":\"velo_at_github\",\"type\":\"preposterous hacker\"}")
.build();
mockClient = new MockClient();
github = Feign.builder().decoder(new AssertionDecoder(new GsonDecoder()))
.client(mockClient.ok(HttpMethod.GET, "/repos/netflix/feign/contributors", data)
.ok(HttpMethod.GET, "/repos/netflix/feign/contributors?client_id=55")
.ok(HttpMethod.GET, "/repos/netflix/feign/contributors?client_id=7 7",
new ByteArrayInputStream(data))
.ok(HttpMethod.POST, "/repos/netflix/feign/contributors",
"{\"login\":\"velo\",\"contributions\":0}")
.ok(postContributorKey, "{\"login\":\"velo\",\"contributions\":0}")
.noContent(HttpMethod.PATCH, "/repos/velo/feign-mock/contributors")
.add(HttpMethod.GET, "/repos/netflix/feign/contributors?client_id=1234567890",
HttpsURLConnection.HTTP_NOT_FOUND)
Expand Down Expand Up @@ -154,6 +158,15 @@ public void paramsEncoding() {

@Test
public void verifyInvocation() {
RequestKey testRequestKey =
RequestKey.builder(HttpMethod.POST, "/repos/netflix/feign/contributors")
.headers(RequestHeaders.builder()
.add("Content-Length", "55")
.add("Content-Type", "application/json")
.build())
.body("{\"login\":\"velo_at_github\",\"type\":\"preposterous hacker\"}")
.build();

Contributor contribution =
github.create("netflix", "feign", "velo_at_github", "preposterous hacker");
// making sure it received a proper response
Expand All @@ -164,7 +177,11 @@ public void verifyInvocation() {
List<Request> results =
mockClient.verifyTimes(HttpMethod.POST, "/repos/netflix/feign/contributors", 1);
assertThat(results, hasSize(1));
results = mockClient.verifyTimes(testRequestKey, 1);
assertThat(results, hasSize(1));


assertThat(mockClient.verifyOne(testRequestKey).body(), notNullValue());
byte[] body = mockClient.verifyOne(HttpMethod.POST, "/repos/netflix/feign/contributors")
.body();
assertThat(body, notNullValue());
Expand All @@ -178,9 +195,51 @@ public void verifyInvocation() {

@Test
public void verifyNone() {
RequestKey testRequestKey;
github.create("netflix", "feign", "velo_at_github", "preposterous hacker");
mockClient.verifyTimes(HttpMethod.POST, "/repos/netflix/feign/contributors", 1);

testRequestKey =
RequestKey.builder(HttpMethod.POST, "/repos/netflix/feign/contributors")
.charset(UTF_8)
.headers(RequestHeaders.builder()
.add("Content-Length", "55")
.add("Content-Type", "application/json")
.build())
// body is not equal
.body("{\"login\":\"velo[at]github\",\"type\":\"preposterous hacker\"}")
.build();
try {
mockClient.verifyOne(testRequestKey);
fail();
} catch (VerificationAssertionError e) {
assertThat(e.getMessage(), containsString("Wanted"));
assertThat(e.getMessage(), containsString("POST"));
assertThat(e.getMessage(), containsString("/repos/netflix/feign/contributors"));
}
mockClient.verifyNever(testRequestKey);

testRequestKey =
RequestKey.builder(HttpMethod.POST, "/repos/netflix/feign/contributors")
.charset(UTF_8)
.headers(RequestHeaders.builder()
.add("Content-Length", "55")
.add("Content-Type", "application/json")
// headers are not equal
.add("X-Header", "qwerty")
.build())
.body("{\"login\":\"velo_at_github\",\"type\":\"preposterous hacker\"}")
.build();
try {
mockClient.verifyOne(testRequestKey);
fail();
} catch (VerificationAssertionError e) {
assertThat(e.getMessage(), containsString("Wanted"));
assertThat(e.getMessage(), containsString("POST"));
assertThat(e.getMessage(), containsString("/repos/netflix/feign/contributors"));
}
mockClient.verifyNever(testRequestKey);

try {
mockClient.verifyTimes(HttpMethod.POST, "/repos/netflix/feign/contributors", 0);
fail();
Expand Down

0 comments on commit 2cb3fca

Please sign in to comment.