Dewey
Dewey

Reputation: 892

SoapUI: How to cast 0 as 'false'

I'm using SoapUI to test a WCF service. I have an XPath Match assertion in which the Declare is:

if (boolean(//a:IsClick/text()[1])) then //a:IsClick else ''

For the source XML, the node is

<a:IsClick>false</a:IsClick>

so the Declare section equates to 'false'.

The Expected box has this:

${#ResponseAsXml#(//CLICK[text()],'')}

and the XML (from a JDBC Test Step) is:

<CLICK>0</CLICK>

so the expected value is 0.

I need to have these two equate so my assertion will pass. One way to do this would be to cast the Expected result from 0 to 'false'. How can I do that? Or is there a better approach?

Upvotes: 0

Views: 1635

Answers (3)

dmahapatro
dmahapatro

Reputation: 50265

assert  '1'.toInteger().asBoolean()
assert !'0'.toInteger().asBoolean()

Upvotes: 0

albciff
albciff

Reputation: 18517

In XPath the boolean() function returns a boolean for number, string, or node-set. In your case where you want to cast a number to a boolean, boolean(0) returns false, for the rest of numbers boolean(n) returns true. In the other hand boolean() of string returns false for boolean('false') or for boolean('') (empty string) for the rest of strings boolean() returns true. So your problem is that using text() you're getting the '0' as string instead of a number so when you try to cast boolean('0') you're getting true.

In your case if you've some XML result from your JDBC Test Step like:

<Results>
    <CLICK>0</CLICK>
</Results>

You can convert this 0 to false adding boolean() to your expression and also using number() function instead of text(). So to cast the 0 to false use:

${#ResponseAsXml#(boolean(//CLICK[number()]))}

instead of:

${#ResponseAsXml#(//CLICK[text()],'')}

Hope this helps,

Upvotes: 1

SiKing
SiKing

Reputation: 10329

The simplest solution is to turn this into a Groovy problem - a Groovy assertion.

Here is a visualization (see documentation):

def negIsClick = "false"
def negCLICK = "0"

def posIsClick = "true"
def posCLICK = "1"

// fake "cast" the text to boolean
assert !(negIsClick.equals("true") ?: false)
assert (posIsClick.equals("true") ?: false)

assert !negCLICK.toInteger()   // zero is false
assert posCLICK.toInteger()    // all other numbers are true

// note the exclamations everywhere
assert !(negIsClick.equals("true") ?: false) == !negCLICK.toInteger()
assert !(posIsClick.equals("true") ?: false) == !posCLICK.toInteger()
// this fails
assert (negIsClick.equals("true") ?: false) == negCLICK.toInteger()

The last one fails, because you cannot compare a boolean to an integer. But in the cases before that, the ! first casts everything to booleans.

So in your case, you will need to do something like:

// read in the two values
def IsClick = context.expand( '${XML test step#Response//*:IsClick}' )
def CLICK = context.expand( '${JDBC test step#ResponseAsXml//*:CLICK}' )
// now compare them
assert !(IsClick.equals("true") ?: false) == !CLICK.toInteger()

Upvotes: 0

Related Questions