Я новичок в Kotlin и Groovy и не уверен, насколько это возможно, чтобы достичь этого.
У меня есть http-клиент, который делает удаленные звонки
class MyClient @Inject constructor(private val httpClient: HttpClient, private val config: MyConfig) {
fun GetStuff(id: Id): Promise<MyResponse> { ...}
}
Тогда есть конфигурация MyApiApp со случайной привязкой и регистрациями
А потом AbstractModule, который из того, что я вижу во внешней библиотеке для создания более читаемой конфигурации:
class ApiModule : AbstractModule() {
protected override fun configure() {
bind(MyEndpoint::class.java)
}
MyEndpoint вводится в конфигурацию myApp, и конечные точки становятся доступными. Конечная точка работает хорошо, но ниже приведен псевдокод, который примерно показывает, что он делает.
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() }
}
}
}
}
}
}
А теперь к вопросу.
Я пишу нестандартные интеграционные тесты и хочу сделать httpCall на мой ratpack-сервер, но я хочу, чтобы последующие вызовы myClient были смоделированы для устранения зависимостей.
@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
}
И здесь кроется проблема.
Конечная точка foo успешно ударилась, но myClient не подвергается насмешкам. BindingImposition что-то делает, потому что он заменяет myClient на тот, в котором есть нулевой HttpClient.
Возможно ли каким-то образом ввести поддельный клиент в мою конечную точку?
Я бы предпочел не создавать EmbeddedApp, а просто издеваться над MyClient.
Я также попробовал UserRegistryImpositions, но до сих пор мне не удавалось должным образом издеваться над MyClient.
Я добился этого с помощью .NET Core 2, но не нашел способа использовать эту платформу.
Любая помощь очень ценится. Спасибо