There has been different ways to mock the response from an API call, We do have a lot of good frameworks for this purpose. But, what if we need to give back a mock response according to the request and its parameters. That is what this library is all about. Raccoon is an interceptor plugin that will help the developer to mock a response back according to the request. The library uses Reflection apis under the hood to do the whole process.
Insights
The integration of this library is soo much compact in such a way that the developer doesn't need to take much time for the process. We basically need to make main 3 additions:
Add the Interceptor Plugin
Add Service class in the AndroidTest directory
Add Controller class and the endpoint definition in the AndroidTest directory.
Gradle
Add the following to your project's root build.gradle.kts file
Add the following to your project's build.gradle.kts file
dependencies {
// Other dependencies
implementation("com.github.iamjosephmj:Raccoon:1.0.5")
}
Basic usage
Add interceptor plugin
Retrofit
Retrofit users need to add the RaccoonOkHttpPlugin as the interceptor
val okHttpClient =OkHttpClient.Builder()
.addInterceptor(RaccoonOkHttpPlugin())
.build()
val retrofit =Retrofit.Builder()
.client(okHttpClient)
.build()
Adding this plugin to the real project doesn't hurt until the RaccoonStub class is initialized.
Add Controller Class
This is one of the core classes that Raccoon library is looking into. Controller class is the place were the Endpoint definitions are made. Developers can keep the logically related Endpoints in the same Controller
.buildRaccoonResponse(statusCode = 200 /* STATUS code of the api response */)
}
override fun tearDown() {
// clean up memory.
}
}
">
@ControllerModule
classMockController : RaccoonController() {
overridefunsetup() {
// Do the DI related stuff
}
@RaccoonEndpoint(
endpoint ="your endpoint",
responseTime =100, /* delay in api response delivery */RaccoonRequestType.GET/* user can define their request types here */
)
funfetchToDoList(@Params headers:Parameters): RaccoonResponse {
return</* Your response object */>
.buildRaccoonResponse(statusCode =200/* STATUS code of the api response */)
}
overridefuntearDown() {
// clean up memory.
}
}
setUp()
If user wishes to import some objects via DI, this function will be entry point to do the same. This function is called before the endpoint endpoint definition is called.
tearDown()
This function is the best candidate to free up the memory after the endpoint point definition execution. This function is called after the endpoint endpoint definition is called.
Endpoint Definition function
The user can define any names to the endpoint definition function. The only requirement that the library has is that the user should give an @RaccoonEndpoint for the same. Take the example above example to see the annotation in action.
The Endpoint Definition function has a return type RaccoonResponse. The developer can either directly create RaccoonResponse object with
RaccoonResponse(
statusCode=200,
body =/* json string */"{ ... }"
)
or they can use the Moshi/Gson supported pojo objects. Raccoon provides a helper extension function buildRaccoonResponse to do the same
return</* Your response object */>
.buildRaccoonResponse(statusCode =200/* STATUS code of the api response */)
You can also include multiple controllers in single controller class to maintain modularity in your project.
@ControllerModule(includeControllers = [MockController2::class/* you can add any number of controllers here */])
classMockController : RaccoonController() {
// your implementation ...
}
Take a look at the androidTest implementation to get more insights on the same.
Add Service Class
Service class helps the library to create an overall understanding about how to efficiently parse through controllers to fetch the endpoint.
Add @RaccoonService as the annotation for the Service class.
Add @RaccoonController as the annotation for mock controller class provider function.
Test class implementation
@RunWith(AndroidJUnit4::class)
classMainActivityTest {
@Before
funsetup() {
// setupRaccoonStub.setUp(
RaccoonConfig.Builder()
.addService(MockService::class)
.addService(MockService2::class)
.addService(MockService3::class)
.setParserType(GsonPlugin())
.build()
)
/* * The developer can also use {@see MoshiPlugin} as the parserType as per the project * requirements*/
}
/** * You should not launch the activity before the RaccoonStub initialization. * There can be scenarios where the app calls the API on launch. In such cases only launch the * Activity inside the test function*/
@get:Rule
val rule =ActivityTestRule(
MainActivity::class.java, false, false
)
@Test
funuseAppContext() {
// run your test
}
@After
funtearDown() {
// cleans up the memory.RaccoonStub.teatDown()
}
}
Contribution, Issues or Future Ideas
If part of Raccoon is not working correctly be sure to file a Github issue. In the issue provide as many details as possible. This could include example code or the exact steps that you did so that everyone can reproduce the issue. Sample projects are always the best way :). This makes it easy for our developers or someone from the open-source community to start working!
If you have a feature idea submit an issue with a feature request or submit a pull request and we will work with you to merge it in!
Contribution guidelines
Contributions are more than welcome!
You should make sure that all the tests are working properly.
You should raise a PR to develop branch
Before you raise a PR please make sure your code had no issue from Android studio lint analyzer.
Please Share & Star the repository to keep me motivated.
Looking at the readme, it might be beneficial to add a junit test rule to setup and teardown Raccoon without adding the extra methods in the test class. It would also allow you to wrap the raccoon test rule around the ActivityTestRule and support launching the activity default.