Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mock] verifyTimes with RequestKey parameter #1517

Merged
merged 3 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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