0

Here is the sample test i have prepared to check whether metaclass method replacement works or not. Below is the method under test. This method is inside PaymentController.

Please look at the line

CreateTransactionResponse tresponse = controller.getApiResponse();

in the code. In the test code i am using metaclass to replace getApiResponse() method.

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"


}

Here is the integration test where i replace getApiResponse() method of CreateTransactionController class.When the test is run then this replacement doesnt occur i.e it doesnt print "got here...". So i appreciate any guide as to why this replacement is not working. I appreciate any help. Thanks!

@Test
 void test(){

    PaymentController pc = new PaymentController()


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


    pc.justTest()


 }

UPDATE:

This is strange.

I have changed justTest to another piece of authorize.net test code.

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"

}

here is the test code meta replacement.

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

Here it works. i.e println "asd" is executed. In other words, the postTransaction method of Merchant is replaced. So i am wondering why the replacement is working on Merchant class and not on CreateTransactionController class. I appreciate any insights. Thanks!

UPDATE2: One thing i would like to note down is that the authorize.net library was downloaded as jar and added to lib folder. So the library is not resolved from BuildConfig file. This is because the used grails framework is old 2.2 and the library is new so since it was not in the repository it had to be downloaded as jar and added to lib folder. Could this be breaking the meta replacement?

kofhearts
  • 3,607
  • 8
  • 46
  • 79
  • Does it render "Hello", i.e. does it even get to the getApiResponse call? Also, you may notice your override doesn't return the proper type... maybe add a `return null` after the println? – billjamesdev Mar 28 '19 at 05:01
  • thanks for the comment. Even after adding breakpoint in println "got here.." and running in debug mode this point is not hit. also i have added breakpoint in the code where the call to getApiResponse is made. So getApiResponse is called but the overridden meta method is not called. – kofhearts Mar 28 '19 at 05:19
  • could you look at the update added to the post? – kofhearts Mar 28 '19 at 05:26
  • One more idea, does the getApiResponse method actually take an optional argument? If so, you'll need to have that argument in the closure, even if you're not using it. The signature of the closure override has to match the signature of the overridden method exactly. – billjamesdev Mar 28 '19 at 15:33
  • thanks. that is also checked. the number of arguments match in closure. – kofhearts Apr 03 '19 at 06:17
  • @billjamesdev can you look into this similar issue https://stackoverflow.com/questions/55508397/meta-replacing-same-method-in-two-different-tests-not-working – kofhearts Apr 04 '19 at 05:25

0 Answers0