【问题标题】:Updating a WsdlRequest value via SoapUI Pro通过 SoapUI Pro 更新 WsdlRequest 值
【发布时间】:2014-09-25 18:57:08
【问题描述】:

我想在运行时使用 groovy 更新 WsdlRequest 参数值。 假设我有一个包含两个参数的 WsdlRequest:名称、地址。我想在创建 WsdlSubmit 实例之前将我希望请求具有的值传递给这个 WsdlRequest。我知道基本代码是这样的:

WsdlProject project = new WsdlProject()
WsdlInterface iface = WsdlInterfaceFactory.importWsdl(project, wsdl, true)[0]
WsdlOperation operation = (WsdlOperation) iface.getOperationAt(3)
WsdlRequest request = operation.addNewRequest(requestName)
request.setRequestContent (requestContent);

requestContent 是字符串格式的soapxml。有没有一种插入我的值的好方法(比如我希望名称值是“测试”,地址值是请求的“示例”)?如果我在生成请求时已经拥有该信息,我宁愿不将 xml 存储为字符串并更新它。

这是一个xml的例子:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:data="http://test.com">
   <soapenv:Header/>
   <soapenv:Body>
      <data:updateFieldName>
         <fieldId>?</fieldId>
         <!--Optional:-->
         <newFieldId>?</newFieldId>
      </data:updateFieldName>
   </soapenv:Body>
</soapenv:Envelope>

在创建 WsdlRequest 之前,我创建了一个 groovy 对象,其中包含我想要填充到上述soap xml 消息中的值。假设这个对象声明 fieldId = 10 和 newFieldRequest = 15。我不确定如何将这些值传递到请求中。有没有办法用 SoapUI API 做到这一点?我也有专业许可证。

【问题讨论】:

  • 是否要在某些 xml 节点中添加特定值?你能分享你的xml并解释你想要这个值在哪些节点?
  • 是的,我绝对可以做到。让我现在更新我的问题。谢谢!

标签: groovy soapui


【解决方案1】:

您可以使用XMLHolder 来解析您的xml,并且您可以使用setNodeValue(xpath, value) 来指定此节点的值,在您的情况下如下所示:

import com.eviware.soapui.support.XmlHolder

// your request content
def requestContent = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:data="http://test.com">'+
   '<soapenv:Header/>'+
   '<soapenv:Body>'+
      '<data:updateFieldName>'+
         '<fieldId>?</fieldId>'+
         '<newFieldId>?</newFieldId>'+
      '</data:updateFieldName>'+
   '</soapenv:Body>'+
'</soapenv:Envelope>'

// parse it as xml bean
def requestXml = new XmlHolder(requestContent)
// set your node values
requestXml.setNodeValue("//*:fieldId","10");
requestXml.setNodeValue("//*:newFieldId","15");

然后再次获取string的xml内容可以使用getXml()方法如下:

WsdlRequest request = ...
// to set in your request use getXml()
request.setRequestContent (requestXml.getXml());

有关更多信息,您可以查看XMLHolder api documentation

还有另一种不用 groovy 脚本的方法;使用属性。例如,您可以在 TestCase 中添加一个属性,然后直接在您的 TestStep 请求中使用它,如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:data="http://test.com">
   <soapenv:Header/>
   <soapenv:Body>
      <data:updateFieldName>
         <fieldId>${#TestCase#yourProperty}</fieldId>
         <newFieldId>${#TestCase#anotherProperty}</newFieldId>
      </data:updateFieldName>
   </soapenv:Body>
</soapenv:Envelope>

如果您对此感兴趣,请查看:Working with propertiesproperty expansion

根据评论进行编辑:

我使用公共 wsdl 使用您的代码和 xml 持有者编写了一个完整的示例,因为您可以尝试在没有 NPE 的情况下获得结果并与您的比较以检查发生了什么:

import com.eviware.soapui.impl.wsdl.WsdlProject
import com.eviware.soapui.impl.wsdl.WsdlInterface
import com.eviware.soapui.impl.WsdlInterfaceFactory
import com.eviware.soapui.impl.wsdl.WsdlOperation
import com.eviware.soapui.impl.wsdl.WsdlRequest
import com.eviware.soapui.support.XmlHolder

wsdl = "http://www.webservicex.net/geoipservice.asmx?WSDL"
WsdlProject project = new WsdlProject() 
WsdlInterface iface = WsdlInterfaceFactory.importWsdl(project, wsdl, true )[0] 
WsdlOperation operation = (WsdlOperation) iface.getOperationByName( "GetGeoIP" ) 
WsdlRequest request = operation.addNewRequest("Request") 
def defaultRequest = operation.createRequest(true) 
def xmlHolder = new XmlHolder(defaultRequest)
xmlHolder.setNodeValue("//*:IPAddress","127.0.0.1");
request.setRequestContent (xmlHolder.getXml());

希望这会有所帮助,

【讨论】:

  • 非常感谢。我会试试这些。我同意我应该转向使用 TestSuite/TestCase/TestStep 的心态,这就是 PoC。许多 SoapUI 文档似乎是针对 GUI 用户的,这很重要,但不是我想要领导这个项目的地方。我也不认为将 TestCase 属性用于 TestStep。感谢您的输入!我看到了 GroovyUtils API,我认为我需要使用它来获得 TestStep。
  • 我可以使用 def requestContent = operation.createRequest(true) 来获取传递给 request.setRequestContent(requestContent) 的值吗?我得到一个空指针。我会接受我试图让它工作的答案,但我知道你是对的:)
  • 我也尝试像你一样对字符串进行硬编码,但我仍然得到空指针...试图确定我做错了什么
  • 我认为抛出 NPE 是因为您的 WsdlRequest request 可能为空。
  • 当我如下创建 defaultRequest 时,它不为空。但是当我使用默认请求创建一个 XmlHolder 实例时,我得到了 NPE ...我只是不确定 {WsdlProject project = new WsdlProject(); WsdlInterface iface = WsdlInterfaceFactory.importWsdl(project, wsdl, true )[0]; WsdlOperation 操作 = (WsdlOperation) iface.getOperationByName("getOrdersForContract"); WsdlRequest 请求 = operation.addNewRequest("请求"); def defaultRequest = operation.createRequest(true) def xmlHolder = new XmlHolder(defaultRequest)}
【解决方案2】:

以下是 groovy 脚本:

  1. 更新项目中的所有 WSDL 定义。
  2. 重新创建对更新请求的所有请求。
  3. 备份旧请求。

 import static com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction.recreateRequests
    import static com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction.recreateTestRequests

    project = testRunner.testCase.testSuite.project; //get the project reference
    def ifaceList = project.getInterfaceList(); //get all the interfaces present in the project in a list

    //start a loop for number of interfaces
    for(int i = 0; i < project.getInterfaceCount() ; i++)
    {

    def iface = project.getInterfaceAt(i);
    def url = iface.definition;
    iface.updateDefinition( url, true); //updateDefinition(String url , Boolean createRequests)

    //The above part updates the definition
    //The part below recreates the requests based on updated wsdl definition

    //syntax - 
    //recreateRequests( WsdlInterface iface, boolean buildOptional, boolean createBackups, boolean keepExisting, boolean keepHeaders )

    recreateRequests(iface,true,true,true,true);
    recreateTestRequests(iface,true,true,true,true);
    }
    //End of Script//

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多