Forum Discussion

Poobury's avatar
Poobury
New Contributor
11 years ago

No setter for HTTP Statuses in ValidHttpStatusCodesAssertion

Hi All,

I'm trying to programmatically add a test step to a test case, and I'm having trouble adding assertions to the test step. The problem is that ValidHttpStatusCodesAssertion[/font:25njtky8] doesn't have a setter or getter for the codes[/font:25njtky8] attribute. For example:



// Add our script assertion.
def assertion = newTestStep.addAssertion(GroovyScriptAssertion.LABEL)
assertion.setScriptText('log.info("Test Worked")')

// Check the response time
assertion = newTestStep.addAssertion(ResponseSLAAssertion.LABEL);
assertion.setSLA("200")

// Check the HTTP Status Code
assertion = newTestStep.addAssertion(ValidHttpStatusCodesAssertion.LABEL);


The problem is with the last assertion, in that I need to call assertion.setCodes("200,404")[/font:25njtky8], but, as I say, the class doesn't have a setter for that.

I'm going to try and work around it using reflection, but I thought I'd raise it as an issue, as I'm sure it's just an oversight and not intentional, as it is inconsistent with how the other assertions work.

Many thanks to all for your efforts!

Paul.

4 Replies

  • Poobury's avatar
    Poobury
    New Contributor
    Just to update, I managed to get a reflection solution working in case it helps anyone else:



    // Add a response code assertion.
    assertion = newTestStep.addAssertion(ValidHttpStatusCodesAssertion.LABEL);
    // XXX there isn't a setter for the "codes" fields, so we need to set it via reflection.
    java.lang.reflect.Field statusAssertionCodesField = assertion.getClass().getDeclaredField("codes");
    // Make the private field accessible
    statusAssertionCodesField.setAccessible(true);
    statusAssertionCodesField.set(assertion, "200,404")



    Cheers,

    Paul.
  • nmrao's avatar
    nmrao
    Champion Level 3
    Very nice of you for posting the solution. Hope it will be useful for someone.
    And soapui team might look into the detains and do the needful.
  • Poobury's avatar
    Poobury
    New Contributor
    A pleasure, Rao. Far too many times have I taken from the community (in the technical help sense, not in the "stealing from my next door neighbours" sense ) but not given in return, so it's about time I gave something back!

    On that note, I've since noticed with my workaround that it works fine as long as the project remains open, but if you reload the project, the http status codes that were set are lost. However, I weirdly noticed that if you opened the assertion dialog to view the status code before the project was saved, closed and re-opened, then the status codes were persisted. Looking at the source, I worked out that if I effectively called
    assertion.setConfiguration(assertion.createConfiguration())

    then that resolves the issue.

    However, as usual, nothing is ever easy, and the
    createConfiguration()
    method is protected, so once again, I have to resort to reflection:


    // XXX Invoke assertion.createConfiguration() to copy the assertion "codes" we set above into the configuration to be persisted into the project.
    java.lang.reflect.Method statusAssertionCreateConfigurationMethod = assertion.getClass().getDeclaredMethod("createConfiguration");
    // Make the protected method accessible
    statusAssertionCreateConfigurationMethod.setAccessible(true);

    // Create the configuration and set it on the assertion.
    def assertionConfiguration = statusAssertionCreateConfigurationMethod.invoke(assertion)
    assertion.setConfiguration(assertionConfiguration)
    • nitinmahawadiwa's avatar
      nitinmahawadiwa
      Occasional Contributor

      Thank you Paul,

      I was looking for similar solution on Java, but your script's Reflection suggestion helped me & saved my time as well.