метакласс не заменяет метод экземпляра во время тестирования?

#grails #groovy #grails-2.2

#grails #groovy #grails-2.2

Вопрос:

Вот пример теста, который я подготовил, чтобы проверить, работает ли замена метода метакласса или нет. Ниже приведен тестируемый метод. Этот метод находится внутри PaymentController.

Пожалуйста, посмотрите на строку

 CreateTransactionResponse tresponse = controller.getApiResponse();
  

в коде. В тестовом коде я использую метакласс для замены метода getApiResponse().

 def justTest(){

    def descriptor = params['dataDescriptor']
    def value = params['dataValue']

    String firstName = params[AuthNetField.X_FIRST_NAME.fieldName]
    String lastName = params[AuthNetField.X_LAST_NAME.fieldName]
    String address = params[AuthNetField.X_ADDRESS.fieldName]
    String city = params[AuthNetField.X_CITY.fieldName]
    String state = params[AuthNetField.X_STATE.fieldName]
    String zip = params[AuthNetField.X_ZIP.fieldName]
    String country = params[AuthNetField.X_COUNTRY.fieldName]
    String phone = params[AuthNetField.X_PHONE.fieldName]
    String email = params[AuthNetField.X_EMAIL.fieldName]

    String apiLoginId = grailsApplication.config.net.authorize.apiLoginId


    if (grailsApplication.config.net.authorize.environment == net.authorize.Environment.PRODUCTION){
        ApiOperationBase.setEnvironment(Environment.PRODUCTION);
    }
    else{
        ApiOperationBase.setEnvironment(Environment.SANDBOX);
    }

    String transactionKey = grailsApplication.config.net.authorize.transactionKey


    MerchantAuthenticationType merchantAuthenticationType  = new MerchantAuthenticationType() ;
    merchantAuthenticationType.setName(apiLoginId);
    merchantAuthenticationType.setTransactionKey(transactionKey);
    ApiOperationBase.setMerchantAuthentication(merchantAuthenticationType);

    // Populate the payment data
    PaymentType paymentType = new PaymentType();
    OpaqueDataType OpaqueData = new OpaqueDataType();
    OpaqueData.setDataDescriptor(descriptor);
    OpaqueData.setDataValue(value);
    paymentType.setOpaqueData(OpaqueData);


    CustomerDataType cdt = new CustomerDataType()
    cdt.setEmail(email)


    // Create the payment transaction request
    TransactionRequestType txnRequest = new TransactionRequestType();
    txnRequest.setTransactionType(TransactionTypeEnum.AUTH_CAPTURE_TRANSACTION.value());
    txnRequest.setPayment(paymentType);

    txnRequest.setCustomer(cdt)


    txnRequest.setAmount(5);


    // Make the API Request
    CreateTransactionRequest apiRequest = new CreateTransactionRequest();
    apiRequest.setTransactionRequest(txnRequest);
    CreateTransactionController controller = new CreateTransactionController(apiRequest);
    controller.execute();


    CreateTransactionResponse tresponse = controller.getApiResponse();


    render "hello"


}
  

Вот интеграционный тест, в котором я заменяю метод getApiResponse() класса CreateTransactionController.При запуске теста эта замена не происходит, т. Е. не выводится «добрался сюда …». Поэтому я ценю любое руководство относительно того, почему эта замена не работает. Я ценю любую помощь. Спасибо!

 @Test
 void test(){

    PaymentController pc = new PaymentController()


    CreateTransactionController.metaClass.getApiResponse = {
        println "got here..."
    }


    pc.justTest()


 }
  

Обновить:

Это странно.

Я изменил justTest на другую часть authorize.net тестовый код.

 def justTest(){


    String apiLoginId = grailsApplication.config.net.authorize.apiLoginId
    String transactionKey = grailsApplication.config.net.authorize.transactionKey

    def voidTransactionResponse = new TransactionResponse()
    net.authorize.aim.Result<net.authorize.aim.Transaction> voidResult

    Merchant merchant = Merchant.createMerchant(grailsApplication.config.net.authorize.environment, apiLoginId, transactionKey)
    net.authorize.aim.Transaction transaction = merchant.createAIMTransaction(net.authorize.TransactionType.VOID, new BigDecimal(2))
    transaction.transactionId = "324234234"
    voidResult = merchant.postTransaction(transaction)


    render "hello"

}
  

вот метазамена тестового кода.

 PaymentController pc = new PaymentController()
Merchant.metaClass.postTransaction = { net.authorize.Transaction transaction ->
        println "asd"
    }    
pc.justTest()
  

Здесь это работает. т.е. выполняется println «asd». Другими словами, метод посттранзакции Merchant заменен. Итак, мне интересно, почему замена работает в классе Merchant, а не в классе CreateTransactionController. Я ценю любую информацию. Спасибо!

UPDATE2: Одна вещь, которую я хотел бы отметить, заключается в том, что authorize.net библиотека была загружена как jar и добавлена в папку lib. Таким образом, библиотека не разрешена из файла BuildConfig. Это связано с тем, что используемая платформа grails является старой 2.2, а библиотека новой, поэтому, поскольку ее не было в репозитории, ее пришлось загрузить как jar и добавить в папку lib. Может ли это привести к нарушению мета-замены?

Комментарии:

1. Выдает ли он «Привет», т. Е. Доходит ли он вообще до вызова getApiResponse? Также вы можете заметить, что ваше переопределение не возвращает правильный тип… может быть, добавить return null после println?

2. спасибо за комментарий. Даже после добавления точки останова в println «добрался сюда ..» и запуска в режиме отладки эта точка не достигнута. также я добавил точку останова в коде, где выполняется вызов getApiResponse. Итак, вызывается getApiResponse, но переопределенный мета-метод не вызывается.

3. не могли бы вы взглянуть на обновление, добавленное к сообщению?

4. Еще одна идея, действительно ли метод getApiResponse принимает необязательный аргумент? Если это так, вам нужно будет включить этот аргумент в закрытие, даже если вы его не используете. Сигнатура переопределения закрытия должна точно соответствовать сигнатуре переопределяемого метода.

5. Спасибо. это также проверяется. количество аргументов совпадает при закрытии.