如何模拟实现不属于后者的接口(interface)和方法的对象?我需要aplicacaoPT来实现BindingProvider和buscaAplicacaoPorCodigo。强制转换有效,但是buscaAplicacaoPorCodigo调用给出了 MissingMethodException 。我尝试了一张 map 和一个Expando:
import static org.junit.Assert.*
import grails.test.mixin.*
import grails.test.mixin.support.*
import org.junit.*
import javax.xml.ws.BindingProvider
@TestMixin(GrailsUnitTestMixin)
class CatalogClientServiceTests {
void testFetch() {
AplicacaoSoapService.metaClass.getAplicacaoSoapPort = {
[ getRequestContext: { new HashMap<String, Object>() },
buscaAplicacaoPorCodigo: { String appCode -> "carrapato!" } ] as BindingProvider
}
def applicationDataFromCatalog = service.fetch("dino")
}
void testFetchFailsWithInvalidApplicationCode() {
AplicacaoSoapService.metaClass.getAplicacaoSoapPort = {
def aplicacaoSoapPort = new Expando()
aplicacaoSoapPort.getRequestContext = { new HashMap<String, Object>() }
aplicacaoSoapPort.buscaAplicacaoPorCodigo = { String appCode -> "castanha!" }
aplicacaoSoapPort as BindingProvider
}
shouldFail(IllegalArgumentException) { service.fetch("dino") }
}
}
import javax.xml.ws.BindingProvider
class CatalogClientService {
def aplicacaoPT = new AplicacaoSoapService().getAplicacaoSoapPort()
def grailsApplication
def fetch(String appCode) {
Map<String, Object> req_ctx = ((BindingProvider)aplicacaoPT).getRequestContext();
req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, grailsApplication.config.catalogAppEndPointAddress);
def response = aplicacaoPT.buscaAplicacaoPorCodigo(appCode)
println "response: $response"
}
}
我还尝试将buscaAplicacaoPorCodigo添加到BindingProvider的元类中,但它坚持使用所有测试的实现之一。在下面的示例中,将在上方打印响应“castanha!”。或“carrapato!”在每次运行的两个测试中。
import static org.junit.Assert.*
import grails.test.mixin.*
import grails.test.mixin.support.*
import org.junit.*
import javax.xml.ws.BindingProvider
@TestMixin(GrailsUnitTestMixin)
class CatalogClientServiceTests {
void testFetch() {
BindingProvider.metaClass.buscaAplicacaoPorCodigo = { String appCode -> "carrapato!" }
AplicacaoSoapService.metaClass.getAplicacaoSoapPort = {
[ getRequestContext: { new HashMap<String, Object>() } ] as BindingProvider
}
def applicationDataFromCatalog = service.fetch("dino")
}
void testFetchFailsWithInvalidApplicationCode() {
BindingProvider.metaClass.buscaAplicacaoPorCodigo = { String appCode -> "castanha!" }
AplicacaoSoapService.metaClass.getAplicacaoSoapPort = {
def aplicacaoSoapPort = new Expando()
aplicacaoSoapPort.getRequestContext = { new HashMap<String, Object>() }
aplicacaoSoapPort as BindingProvider
}
shouldFail(IllegalArgumentException) { service.fetch("dino") }
}
}
为了简单起见,我剥离了上面的代码。
我希望其中一些可以帮助我! :)
最佳答案
我对grails的使用经验为零,但这似乎与代理相关。结果代理没有可用的buscaAplicacaoPorCodigo
。
在AFAIK中,您有两种选择:使用Buscador
创建接口(interface)buscaAplicacaoPorCodigo
,并创建super interface for both BindingProvider
and Buscador
,或者对于纯动态解决方案,使用metaClass作为结果的代理expando:
我 mock 了您的某些类(class),希望我做对了。
BindingProvider.groovy:
interface BindingProvider {
def getRequestContext()
}
其余的:
class AplicacaoSoapService {
static BindingProvider getAplicacaoSoapPort() {
assert false, "Nope, must be mocked"
}
}
AplicacaoSoapService.metaClass.static.getAplicacaoSoapPort = {
def e = new Expando(
getRequestContext: { [:] }) as BindingProvider
e.getMetaClass().buscaAplicacaoPorCodigo = { String a -> "amendoa!" }
e
}
def provider = AplicacaoSoapService.aplicacaoSoapPort
assert provider.buscaAplicacaoPorCodigo("pudim") == "amendoa!"