From b184ebcbfc2ff9ebb7dadd4225af7d3a1e15fd29 Mon Sep 17 00:00:00 2001 From: Andrei Lapshin Date: Wed, 1 Mar 2017 19:38:19 +0300 Subject: [PATCH 1/8] Implementation of pure JVM-based RESTMockFileParser --- .../androidsample/junit/JUnitExampleTest.java | 109 ++++++++++++++++++ .../io/appflate/restmock/JVMFileParser.java | 31 +++++ 2 files changed, 140 insertions(+) create mode 100644 androidsample/src/test/java/io/appflate/restmock/androidsample/junit/JUnitExampleTest.java create mode 100644 core/src/main/java/io/appflate/restmock/JVMFileParser.java diff --git a/androidsample/src/test/java/io/appflate/restmock/androidsample/junit/JUnitExampleTest.java b/androidsample/src/test/java/io/appflate/restmock/androidsample/junit/JUnitExampleTest.java new file mode 100644 index 0000000..ffe5615 --- /dev/null +++ b/androidsample/src/test/java/io/appflate/restmock/androidsample/junit/JUnitExampleTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 Scott Johnson, jaywir3@gmail.com + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package io.appflate.restmock.androidsample.junit; + +import org.junit.Before; +import org.junit.Test; +import org.robolectric.Robolectric; + +import java.util.List; + +import javax.inject.Inject; + +import io.appflate.restmock.JVMFileParser; +import io.appflate.restmock.RESTMockServer; +import io.appflate.restmock.RESTMockServerStarter; +import io.appflate.restmock.androidsample.domain.GithubApi; +import io.appflate.restmock.androidsample.model.Repository; +import io.appflate.restmock.androidsample.model.User; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +import static io.appflate.restmock.utils.RequestMatchers.pathEndsWith; +import static junit.framework.Assert.assertEquals; + +public class JUnitExampleTest { + + public static final String USERNAME_JWIR3 = "jwir3"; + public static final String PATH_JWIR3_PROFILE = "users/jwir3/profile.json"; + public static final String PATH_JWIR3_REPOS = "users/jwir3/repos.json"; + private static final String PATH_USER_NOT_FOUND = "users/user_not_found.json"; + private static final String REPOS = "/repos"; + + // Data about my github profile to check against. + public static final String JWIR3_NAME = "Scott Johnson"; + public static final String JWIR3_COMPANY = "Aperture Science"; + public static final String JWIR3_BLOG = "www.jwir3.com"; + public static final String JWIR3_LOCATION = "Burnsville, MN, USA"; + public static final String JWIR3_EMAIL = "jaywir3@gmail.com"; + + @Inject + GithubApi api; + + @Before + public void setUp() { + // Be sure to reset the server before each test + RESTMockServerStarter.startSync(new JVMFileParser()); + Retrofit retrofit = new Retrofit.Builder() + .baseUrl(RESTMockServer.getUrl()) + .addConverterFactory(GsonConverterFactory.create()) + .build(); + + api = retrofit.create(GithubApi.class); + } + + @Test + public void testValidUser() throws Exception { + RESTMockServer.whenGET(pathEndsWith(USERNAME_JWIR3)).thenReturnFile(200, PATH_JWIR3_PROFILE); + + // Note: This is not recommended in non-test code, since this is a blocking call. + // TODO: Use RxJava magic here to make this easier to show how to accomplish asynchronously. + Response response = api.getUserProfile(USERNAME_JWIR3).execute(); + assertEquals(200, response.code()); + + User jwir3 = response.body(); + assertEquals(JWIR3_NAME, jwir3.name); + assertEquals(JWIR3_BLOG, jwir3.blog); + assertEquals(JWIR3_COMPANY, jwir3.company); + assertEquals(JWIR3_EMAIL, jwir3.email); + assertEquals(JWIR3_LOCATION, jwir3.location); + } + + @Test + public void testNotFound() throws Exception { + RESTMockServer.whenGET(pathEndsWith(USERNAME_JWIR3)).thenReturnFile(404, PATH_USER_NOT_FOUND); + + // Note: This is not recommended in non-test code, since this is a blocking call. + // TODO: Use RxJava magic here to make this easier to show how to accomplish asynchronously. + Response res = api.getUserProfile(USERNAME_JWIR3).execute(); + assertEquals(404, res.code()); + } + + @Test + public void testShowRepos() throws Exception { + RESTMockServer.whenGET(pathEndsWith(REPOS)).thenReturnFile(200, PATH_JWIR3_REPOS); + + // Note: This is not recommended in non-test code, since this is a blocking call. + // TODO: Use RxJava magic here to make this easier to show how to accomplish asynchronously. + Response> res = api.getUserRepos(USERNAME_JWIR3).execute(); + assertEquals(200, res.code()); + + List repos = res.body(); + assertEquals(29, repos.size()); + } +} \ No newline at end of file diff --git a/core/src/main/java/io/appflate/restmock/JVMFileParser.java b/core/src/main/java/io/appflate/restmock/JVMFileParser.java new file mode 100644 index 0000000..6130f73 --- /dev/null +++ b/core/src/main/java/io/appflate/restmock/JVMFileParser.java @@ -0,0 +1,31 @@ +package io.appflate.restmock; + +import java.io.File; +import java.net.URL; +import java.util.Scanner; + +/** + * An implementation of {@link RESTMockFileParser} that allows the retrieval and parsing of files on + * the local filesystem. This does not require an Android dependencies to be set up, so it can be + * used when running within Unit Tests. + */ +public class JVMFileParser implements RESTMockFileParser { + @Override + public String readJsonFile(String jsonFilePath) throws Exception { + ClassLoader classLoader = this.getClass().getClassLoader(); + URL resource = classLoader.getResource(jsonFilePath); + File file = new File(resource.getPath()); + StringBuilder fileContents = new StringBuilder((int)file.length()); + Scanner scanner = new Scanner(file, "UTF-8"); + String lineSeparator = System.getProperty("line.separator"); + + try { + while (scanner.hasNextLine()) { + fileContents.append(scanner.nextLine()).append(lineSeparator); + } + return fileContents.toString(); + } finally { + scanner.close(); + } + } +} From 130060cdb329702430b1cc2ab13c7372f52ea036 Mon Sep 17 00:00:00 2001 From: Andrzej Chmielewski Date: Mon, 10 Apr 2017 09:17:34 +0200 Subject: [PATCH 2/8] Update README.md --- README.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index fe96c34..88d51c3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-RESTMock-green.svg?style=true)](https://android-arsenal.com/details/1/3468) [![Circle CI](https://circleci.com/gh/andrzejchm/RESTMock.svg?style=svg)](https://circleci.com/gh/andrzejchm/RESTMock) REST API mocking made easy. -##About + +## About RESTMock is a library working on top of Square's [okhttp/MockWebServer](https://github.com/square/okhttp/tree/master/mockwebserver). It allows you to specify [Hamcrest](https://github.com/hamcrest/JavaHamcrest) matchers to match HTTP requests and specify what response to return. It is as easy as: ```java @@ -25,7 +26,7 @@ RESTMockServer.whenGET(pathContains("users/defunkt")) ## Setup Here are the basic rules to set up RESTMock for Android -####Step 1: Repository +#### Step 1: Repository Add it in your root build.gradle at the end of repositories: ```groovy @@ -36,7 +37,7 @@ allprojects { } } ``` -####Step 2: Dependencies +#### Step 2: Dependencies Add the dependency ```groovy @@ -45,7 +46,7 @@ dependencies { } ``` -####Step 3: Start the server +#### Step 3: Start the server It's good to start server before the tested application starts, there are few methods: ##### a) RESTMockTestRunner @@ -75,9 +76,9 @@ public class MyAppTestRunner extends AndroidJUnitRunner { ``` -####Step 4: Specify Mocks +#### Step 4: Specify Mocks -#####a) Files +##### a) Files By default, the `RESTMockTestRunner` uses `AndroidAssetsFileParser` as a mocks file parser, which reads the files from the assets folder. To make them visible for the RESTMock you have to put them in the correct folder in your project, for example: .../src/androidTest/assets/users/defunkt.json @@ -88,23 +89,23 @@ RESTMockServer.whenGET(pathContains("users/defunkt")) .thenReturnFile(200, "users/defunkt.json"); ``` -#####b) Strings +##### b) Strings If the response You wish to return is simple, you can just specify a string: ```java RESTMockServer.whenGET(pathContains("users/defunkt")) .thenReturnString(200, "{}"); ``` -#####c) MockResponse +##### c) MockResponse If you wish to have a greater control over the response, you can pass the `MockResponse` ```java RESTMockServer.whenGET(pathContains("users/defunkt")).thenReturn(new MockResponse().setBody("").setResponseCode(401).addHeader("Header","Value")); ``` -####Step 5: Request Matchers +#### Step 5: Request Matchers You can either use some of the predefined matchers from `RequestMatchers` util class, or create your own. remember to extend from `RequestMatcher` -####Step 6: Specify API Endpoint +#### Step 6: Specify API Endpoint The most important step, in order for your app to communicate with the testServer, you have to specify it as an endpoint for all your API calls. For that, you can use the ` RESTMockServer.getUrl()`. If you use Retrofit, it is as easy as: ```java @@ -114,7 +115,7 @@ RestAdapter adapter = new RestAdapter.Builder() .build(); ``` -##Response chains +## Response chains You can chain different responses for a single request matcher, all the `thenReturn*()` methods accept varags parameter with response, or you can call those methods multiple times on a single matcher, examples: ```java @@ -131,7 +132,7 @@ RESTMockServer.whenGET(pathEndsWith(path)) .thenReturnString("a single call", "answer no 2", "answer no 3"); ``` -##Response delays +## Response delays Delaying responses is accomplished with the `delay(TimeUnit timeUnit, long delay)` method. Delays can be specified in chain, just like chaining responses: ```java @@ -152,7 +153,7 @@ RESTMockServer.whenGET(pathEndsWith(path)) Which will result in 1st response being delayed by 5 seconds, 2nd response by 10 seconds and 3rd, 4th, 5th... by 15 seconds. -####Interleaving delays with responses +#### Interleaving delays with responses Check out this example: ```java @@ -167,7 +168,7 @@ RESTMockServer.whenGET(pathEndsWith(path)) ``` this will result in `1st call` being delayed by 5 seconds, `2nd call` delayed by 10 seconds, `3rd call` delayed by 15 seconds, another one by 20 seconds, and another by 30 seconds, and then every consecutive response with 40 seconds delay -##Request verification +## Request verification It is possible to verify which requests were called and how many times thanks to `RequestsVerifier`. All you have to do is call one of these: ```java @@ -197,7 +198,7 @@ RequestsVerifier.takeFirst(5); RequestsVerifier.takeAllMatching(isGET()); ``` -##Logging +## Logging RESTMock supports logging events. You just have to provide the RESTMock with the implementation of `RESTMockLogger`. For Android there is an `AndroidLogger` implemented already. All you have to do is use the `RESTMockTestRunner` or call ```java @@ -231,7 +232,7 @@ using `RuntimeEnvironment.application` from within a Robolectric test. ## Android Sample Project You can check out the sample Android app with tests [here](androidsample/) -##License +## License Copyright (C) 2016 Appflate.io From b743e2d71acbfd791095bb7fc68dfaec806bcb40 Mon Sep 17 00:00:00 2001 From: Andrzej Chmielewski Date: Sun, 16 Apr 2017 08:53:50 +0200 Subject: [PATCH 3/8] #56 update okhttp version to 3.7.0 --- androidsample/build.gradle | 3 +-- gradle.properties | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/androidsample/build.gradle b/androidsample/build.gradle index 9fad8cb..e66af28 100644 --- a/androidsample/build.gradle +++ b/androidsample/build.gradle @@ -58,7 +58,6 @@ android { configurations.all { resolutionStrategy { force "com.android.support:support-annotations:${supportLibraryVersion}" - force 'com.squareup.okio:okio:1.8.0' force "com.squareup.okhttp3:okhttp:${okHttpVersion}" } } @@ -103,7 +102,7 @@ dependencies { exclude module: 'recyclerview-v7' } testCompile "org.robolectric:robolectric:3.2.2" - + testCompile project(':android') testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1' //required to resolve robolectric test problems testCompile(project(':core')) { diff --git a/gradle.properties b/gradle.properties index 2e1b203..174adbc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,6 +33,6 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -supportLibraryVersion=25.2.0 -okHttpVersion=3.4.1 +supportLibraryVersion=25.3.1 +okHttpVersion=3.7.0 org.gradle.configureondemand=true From ec1c1610b1fdafc9524ec83d22bd5b9ce846181e Mon Sep 17 00:00:00 2001 From: Santiago Castro Date: Mon, 17 Apr 2017 19:37:54 -0300 Subject: [PATCH 4/8] Fix broken Markdown headings --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88d51c3..6682429 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ RESTMockServer.whenGET(pathContains("users/defunkt")) **Article** - [ITDD - Instrumentation TDD for Android](https://medium.com/@andrzejchm/ittd-instrumentation-ttd-for-android-4894cbb82d37) -##Table of Contents +## Table of Contents - [About](#about) - [Setup](#setup) - [Request verification](#request-verification) From 71f721fb8475b491cbd746c01d1ad3b88165d24b Mon Sep 17 00:00:00 2001 From: Andrzej Chmielewski Date: Sat, 24 Jun 2017 12:23:42 +0200 Subject: [PATCH 5/8] bump okhttp+build tools + compile and target sdk version --- android/build.gradle | 8 ++-- androidsample/build.gradle | 8 ++-- build.gradle | 3 +- circle.yml | 6 +-- .../restmock/RequestVerifierTest.java | 41 ++++++++++--------- gradle.properties | 4 +- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 198880c..c811662 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,14 +21,12 @@ apply from: '../quality_tools/findbugs.gradle' group = 'com.github.andrzejchm' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 26 + buildToolsVersion "25.0.3" defaultConfig { minSdkVersion 10 - targetSdkVersion 25 - versionCode 1 - versionName "1.0" + targetSdkVersion 26 } buildTypes { release { diff --git a/androidsample/build.gradle b/androidsample/build.gradle index e66af28..4491a30 100644 --- a/androidsample/build.gradle +++ b/androidsample/build.gradle @@ -30,13 +30,13 @@ apply plugin: 'android-apt' apply from: '../quality_tools/findbugs.gradle' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 26 + buildToolsVersion "25.0.3" defaultConfig { applicationId "io.appflate.restmock.androidsample" - minSdkVersion 10 - targetSdkVersion 25 + minSdkVersion 14 + targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner 'io.appflate.restmock.androidsample.CustomTestRunner' diff --git a/build.gradle b/build.gradle index c763bf7..b52616f 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.0' + classpath 'com.android.tools.build:gradle:2.3.2' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' // NOTE: Do not place your application dependencies here; they belong @@ -33,6 +33,7 @@ allprojects { repositories { jcenter() maven { url "https://jitpack.io" } + maven { url "https://maven.google.com" } } version = "0.2.1" } diff --git a/circle.yml b/circle.yml index bac4750..2724649 100644 --- a/circle.yml +++ b/circle.yml @@ -10,9 +10,9 @@ machine: ## Customize dependencies dependencies: pre: - - echo y | android update sdk --no-ui --all --filter "tools,build-tools-24,platform-tools" - - echo y | android update sdk --no-ui --all --filter "android-25" - - echo y | android update sdk --no-ui --all --filter "build-tools-25.0.2" + - echo y | android update sdk --no-ui --all --filter "tools,build-tools-25,platform-tools" + - echo y | android update sdk --no-ui --all --filter "android-26" + - echo y | android update sdk --no-ui --all --filter "build-tools-25.0.3" - echo y | android update sdk --no-ui --all --filter "platform-tools-preview" - echo y | android update sdk --no-ui --all --filter "build-tools-25,extra-google-m2repository,xtra-android-support,extra-android-m2repository" ## Customize test commands diff --git a/core/src/test/java/io/appflate/restmock/RequestVerifierTest.java b/core/src/test/java/io/appflate/restmock/RequestVerifierTest.java index e5a4c75..6a86539 100644 --- a/core/src/test/java/io/appflate/restmock/RequestVerifierTest.java +++ b/core/src/test/java/io/appflate/restmock/RequestVerifierTest.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.util.List; +import java.util.Locale; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.appflate.restmock.exceptions.RequestInvocationCountMismatchException; @@ -120,9 +121,9 @@ public void takesLastNumOfElementsWhenHistoryNotEmpty() throws Exception { List recordedRequests = RequestsVerifier.takeLast(3); assertEquals(3, recordedRequests.size()); - assertEquals("POST", recordedRequests.get(0).getMethod().toUpperCase()); - assertEquals("DELETE", recordedRequests.get(1).getMethod().toUpperCase()); - assertEquals("HEAD", recordedRequests.get(2).getMethod().toUpperCase()); + assertEquals("POST", recordedRequests.get(0).getMethod().toUpperCase(Locale.US)); + assertEquals("DELETE", recordedRequests.get(1).getMethod().toUpperCase(Locale.US)); + assertEquals("HEAD", recordedRequests.get(2).getMethod().toUpperCase(Locale.US)); } @Test @@ -135,10 +136,10 @@ public void takeLastNumOfElementsExceedsHistorySizeTakesWholeHistory() throws Ex List recordedRequests = RequestsVerifier.takeLast(10); assertEquals(4, recordedRequests.size()); - assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase()); - assertEquals("POST", recordedRequests.get(1).getMethod().toUpperCase()); - assertEquals("DELETE", recordedRequests.get(2).getMethod().toUpperCase()); - assertEquals("HEAD", recordedRequests.get(3).getMethod().toUpperCase()); + assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase(Locale.US)); + assertEquals("POST", recordedRequests.get(1).getMethod().toUpperCase(Locale.US)); + assertEquals("DELETE", recordedRequests.get(2).getMethod().toUpperCase(Locale.US)); + assertEquals("HEAD", recordedRequests.get(3).getMethod().toUpperCase(Locale.US)); } @Test(expected = IllegalArgumentException.class) @@ -163,9 +164,9 @@ public void takesFirstNumOfElementsWhenHistoryNotEmpty() throws Exception { List recordedRequests = RequestsVerifier.takeFirst(3); assertEquals(3, recordedRequests.size()); - assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase()); - assertEquals("POST", recordedRequests.get(1).getMethod().toUpperCase()); - assertEquals("DELETE", recordedRequests.get(2).getMethod().toUpperCase()); + assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase(Locale.US)); + assertEquals("POST", recordedRequests.get(1).getMethod().toUpperCase(Locale.US)); + assertEquals("DELETE", recordedRequests.get(2).getMethod().toUpperCase(Locale.US)); } @Test @@ -178,10 +179,10 @@ public void takeFirstNumOfElementsExceedsHistorySizeTakesAllHistory() throws Exc List recordedRequests = RequestsVerifier.takeFirst(10); assertEquals(4, recordedRequests.size()); - assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase()); - assertEquals("POST", recordedRequests.get(1).getMethod().toUpperCase()); - assertEquals("DELETE", recordedRequests.get(2).getMethod().toUpperCase()); - assertEquals("HEAD", recordedRequests.get(3).getMethod().toUpperCase()); + assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase(Locale.US)); + assertEquals("POST", recordedRequests.get(1).getMethod().toUpperCase(Locale.US)); + assertEquals("DELETE", recordedRequests.get(2).getMethod().toUpperCase(Locale.US)); + assertEquals("HEAD", recordedRequests.get(3).getMethod().toUpperCase(Locale.US)); } @Test @@ -194,9 +195,9 @@ public void takesSubsetOfRequests() throws Exception { List recordedRequests = RequestsVerifier.take(1, 4); assertEquals(3, recordedRequests.size()); - assertEquals("POST", recordedRequests.get(0).getMethod().toUpperCase()); - assertEquals("DELETE", recordedRequests.get(1).getMethod().toUpperCase()); - assertEquals("HEAD", recordedRequests.get(2).getMethod().toUpperCase()); + assertEquals("POST", recordedRequests.get(0).getMethod().toUpperCase(Locale.US)); + assertEquals("DELETE", recordedRequests.get(1).getMethod().toUpperCase(Locale.US)); + assertEquals("HEAD", recordedRequests.get(2).getMethod().toUpperCase(Locale.US)); } @Test(expected = IllegalArgumentException.class) @@ -222,9 +223,9 @@ public void takeMatchingFindsAllRelevantRequests() throws Exception { TestUtils.get(path); List recordedRequests = RequestsVerifier.takeAllMatching(RequestMatchers.isGET()); assertEquals(3, recordedRequests.size()); - assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase()); - assertEquals("GET", recordedRequests.get(1).getMethod().toUpperCase()); - assertEquals("GET", recordedRequests.get(2).getMethod().toUpperCase()); + assertEquals("GET", recordedRequests.get(0).getMethod().toUpperCase(Locale.US)); + assertEquals("GET", recordedRequests.get(1).getMethod().toUpperCase(Locale.US)); + assertEquals("GET", recordedRequests.get(2).getMethod().toUpperCase(Locale.US)); } @Test(expected = IllegalArgumentException.class) diff --git a/gradle.properties b/gradle.properties index 174adbc..234f8ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,6 +33,6 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -supportLibraryVersion=25.3.1 -okHttpVersion=3.7.0 +supportLibraryVersion=26.0.0-beta2 +okHttpVersion=3.8.0 org.gradle.configureondemand=true From 128c959437b4394e7a3ac8e2e2a8d8ef46257377 Mon Sep 17 00:00:00 2001 From: Andrzej Chmielewski Date: Sat, 24 Jun 2017 12:43:09 +0200 Subject: [PATCH 6/8] improve logging as for #59 --- .../androidsample/tests/MainActivityTest.java | 8 +++----- .../restmock/MatchableCallsRequestDispatcher.java | 12 +++++++++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/androidsample/src/androidTest/java/io/appflate/restmock/androidsample/tests/MainActivityTest.java b/androidsample/src/androidTest/java/io/appflate/restmock/androidsample/tests/MainActivityTest.java index 2bf4a2e..9bf59d9 100644 --- a/androidsample/src/androidTest/java/io/appflate/restmock/androidsample/tests/MainActivityTest.java +++ b/androidsample/src/androidTest/java/io/appflate/restmock/androidsample/tests/MainActivityTest.java @@ -26,9 +26,7 @@ import io.appflate.restmock.RequestsVerifier; import io.appflate.restmock.androidsample.pageobjects.MainActivityPageObject; import io.appflate.restmock.androidsample.view.activities.MainActivity; -import io.appflate.restmock.utils.RequestMatchers; -import static io.appflate.restmock.RequestsVerifier.verifyRequest; import static io.appflate.restmock.utils.RequestMatchers.pathEndsWith; /** @@ -41,7 +39,8 @@ public class MainActivityTest { private static final String NAME_ANDRZEJ_CHMIELEWSKI = "RESTMock: Andrzej Chmielewski"; private static final String PATH_USER_NOT_FOUND = "mocks/users/user_not_found.json"; private static final String REPOS = "/repos"; - @Rule public ActivityTestRule rule = new ActivityTestRule<>( + @Rule + public ActivityTestRule rule = new ActivityTestRule<>( MainActivity.class, true, false); @@ -68,8 +67,7 @@ public void testGoodAnswer() throws Exception { @Test public void testNotFound() throws Exception { - RESTMockServer.whenGET(pathEndsWith(USERNAME_ANDRZEJCHM)).thenReturnFile(404, - PATH_USER_NOT_FOUND); + RESTMockServer.whenGET(pathEndsWith(USERNAME_ANDRZEJCHM)).thenReturnFile(404, PATH_USER_NOT_FOUND); //launches activity with default intent rule.launchActivity(null); pageObject.typeUsername(USERNAME_ANDRZEJCHM); diff --git a/core/src/main/java/io/appflate/restmock/MatchableCallsRequestDispatcher.java b/core/src/main/java/io/appflate/restmock/MatchableCallsRequestDispatcher.java index 54eb15d..0828b4a 100644 --- a/core/src/main/java/io/appflate/restmock/MatchableCallsRequestDispatcher.java +++ b/core/src/main/java/io/appflate/restmock/MatchableCallsRequestDispatcher.java @@ -60,10 +60,20 @@ private MockResponse onTooManyResponsesMatched(RecordedRequest recordedRequest, } private MockResponse onNoResponsesMatched(RecordedRequest recordedRequest) { - RESTMockServer.getLogger().error("<- Response ERROR:\t" + RESTMockServer.RESPONSE_NOT_MOCKED + ": " + recordedRequest); + RESTMockServer.getLogger() + .error("<- Response ERROR:\t" + RESTMockServer.RESPONSE_NOT_MOCKED + ": " + recordedRequest + + "\n list of mocked requests:\n" + prepareAllMocksMessage()); return createNotMockedResponse(recordedRequest.getMethod()); } + private String prepareAllMocksMessage() { + StringBuilder sb = new StringBuilder(); + for (MatchableCall match : matchableCalls) { + sb.append(match.requestMatcher.toString()).append("\n"); + } + return sb.toString(); + } + private MockResponse createNotMockedResponse(String httpMethod) { MockResponse mockResponse = new MockResponse().setResponseCode(500); if (!httpMethod.equals("HEAD")) { From c9473ee6a1f5b00ca3681173cb1d71893defe948 Mon Sep 17 00:00:00 2001 From: Andrzej Chmielewski Date: Sat, 24 Jun 2017 13:12:32 +0200 Subject: [PATCH 7/8] prove that mockwebserver delays body, not the entire response as for #62 --- .../appflate/restmock/RequestsChainTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/core/src/test/java/io/appflate/restmock/RequestsChainTest.java b/core/src/test/java/io/appflate/restmock/RequestsChainTest.java index 39e0ee2..9a3f2e0 100644 --- a/core/src/test/java/io/appflate/restmock/RequestsChainTest.java +++ b/core/src/test/java/io/appflate/restmock/RequestsChainTest.java @@ -26,11 +26,13 @@ import java.util.concurrent.TimeUnit; import io.appflate.restmock.utils.TestUtils; +import okhttp3.Response; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.RecordedRequest; import static io.appflate.restmock.utils.RequestMatchers.pathEndsWith; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -171,4 +173,24 @@ public void multipleResponsesWithOneDelay() throws Exception { assertEquals(300, b - a, 50); } + @Test + public void delaysBodyNotResponse() throws Exception { + RESTMockServer.whenGET(pathEndsWith(path)) + .thenReturnString("a single call") + .delay(TimeUnit.MILLISECONDS, 500) + .thenReturnString("answer no 2") + .thenReturnString("answer no 3"); + + long a = System.currentTimeMillis(); + Response response = TestUtils.get(path); + assertEquals(200, response.code()); + long b = System.currentTimeMillis(); + assertEquals(0, b - a, 100); + + String body = response.body().string(); + assertNotNull(body); + long c = System.currentTimeMillis(); + assertEquals(500, c - b, 100); + } + } From 6989575155b64e06c1f876cc35f813fcb04498b1 Mon Sep 17 00:00:00 2001 From: Andrzej Chmielewski Date: Sat, 24 Jun 2017 14:32:12 +0200 Subject: [PATCH 8/8] bump version to 0.2.2 --- README.md | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6682429..35bfcae 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Add the dependency ```groovy dependencies { - androidTestCompile 'com.github.andrzejchm.RESTMock:android:0.2.1' + androidTestCompile 'com.github.andrzejchm.RESTMock:android:0.2.2' } ``` diff --git a/build.gradle b/build.gradle index b52616f..5059b5d 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ allprojects { maven { url "https://jitpack.io" } maven { url "https://maven.google.com" } } - version = "0.2.1" + version = "0.2.2" } ext.preDexLibraries = project.hasProperty('preDexLibraries')