Reputation: 2907
I'm new to Kotlin and Groovy and not sure how feasible it is to achieve this.
I have an http client that makes remote calls
class MyClient @Inject constructor(private val httpClient: HttpClient, private val config: MyConfig) {
fun GetStuff(id: Id): Promise<MyResponse> { ...}
}
Then there MyApiApp configuration with random binding and registrations
And then an AbstractModule which from what I can see an external library to create a more readable configuration:
class ApiModule : AbstractModule() {
protected override fun configure() {
bind(MyEndpoint::class.java)
}
MyEndpoint gets injected into the configuration of myApp and the endpoints become available. The endpoint works well but the below is a pseudocode that shows roughly what it does.
class MyEndpoint @Inject constructor(val mClient:MyClient) : Action<Chain> {
override fun execute(chain: Chain) {
chain.path("foo") { ctx ->
ctx.byMethod { method ->
method
.post { ->
ctx.request.body
.then { requestBody ->
Blocking.get {
val id = OBJECT_MAPPER.readValue(requestBody.getText(), Id::class.java)
val data: ComponentResult<MyResponse> = Blocking.on(myClient.GetStuff(id))
data.result!!
}
.onError { throw Exception(it.message) }
.then { tx.response.status(HttpResponseStatus.OK.code()).send() }
}
}
}
}
}
}
And now to the question. I am writing groovy integration tests and I want to make httpCall to my ratpack server but I want the subsequent calls to myClient to be mocked to eliminate dependencies.
@Shared UUID Id= UUID.fromString("c379ad2f-fca4-485c-a676-6988e2c8ef82")
private MyClient mockClient = GroovyMock(MyClient)
private MyEndpoint myEndpoint = new MyEndpoint(mockClient)
@AutoCleanup
private aut = new MainClassApplicationUnderTest(MyApiApp) {
@Override
protected void addImpositions(final ImpositionsSpec impositions) {
impositions.add(BindingsImposition.of {
it.bindInstance (MyEndpoint, myEndpoint)
})
}
}
@Delegate
TestHttpClient client = aut.httpClient
void 'Make a call and the client should be mocked'() {
when:
final response = client.requestSpec { spec ->
spec.body { b ->
b.type("application/json")
b.text("{\"Id\": \"$Id \"}")
}
}.post('foo')
then:
1 * mockClient.GetStuff(Id) >> { throw new Exception("Fail") }
and:
response.status.code == 500
}
And here lies the problem. The endpoint foo gets hit successfully but the myClient isn't mocked. the BindingImposition does something because it replaces myClient with one that has null HttpClient inside it.
Is it somehow possible to inject a mocked client into my endpoint? I would prefer not to create an EmbeddedApp, but to just mock MyClient. I also tried UserRegistryImpositions but so far I haven't managed to properly mock MyClient.
I have achieved this using .NET Core 2, but haven't found the way using this framework.
Any help is very appreciated. Thanks
Upvotes: 0
Views: 405