我是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() }
}
}
}
}
}
}
现在是问题。 我正在编写groovy集成测试,并且想对我的ratpack服务器进行httpCall,但是我希望对随后对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的myClient。
是否可以将模拟的客户端注入我的端点? 我宁愿不要创建EmbeddedApp,而要模拟MyClient。 我还尝试了UserRegistryImpositions,但到目前为止,我还没有正确模拟MyClient。
我已经使用.NET Core 2实现了这一目标,但是还没有找到使用此框架的方法。
我们非常感谢您的帮助。谢谢
答案 0 :(得分:0)
我通过使用界面来使其工作