buscaAplicacaoPorCodigo

buscaAplicacaoPorCodigo

如何模拟实现不属于后者的接口(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!"

09-03 19:24