我想使用文件中的XML来模拟\ SoapClient的响应。
如何在SoapClient从文件返回时创建stdClass对象。
客户端已经包装了SoapClient,因此可以轻松模拟响应。
我的模仿是这样的:
$soapClient->expects($this->once())
->method('call')
->will(
$this->returnValue(
simplexml_load_string(
file_get_contents(__DIR__ . '/../../../Resources/file.xml')
)
)
);
但是这会返回SimpleXml而不是stdClass。
更新
建议的json_encode / json_decode hack似乎没有处理属性,因为SoapClient返回它们:
SoapClient:
object(stdClass)[4571]
public 'Lang' => string 'de' (length=2)
public 'Success' => boolean true
哈克:
object(stdClass)#27 (3) {
["@attributes"]=>
object(stdClass)#30 (2) {
["Lang"]=>
string(2) "de"
["Success"]=>
string(4) "true"
答案 0 :(得分:2)
您可以按如下方式对json进行json编码/解码:
$soapClient->expects($this->once())
->method('call')
->will(
$this->returnValue(
json_decode(json_encode(
simplexml_load_string(
file_get_contents(__DIR__ . '/../../../Resources/file.xml')
)
))
)
);
但我建议明确将预设响应定义为php类。
答案 1 :(得分:1)
如Alex Blex所说,您必须嘲笑__doRequest
。
请参阅PHP的来源:
do_request
在您的SoapClient实例上调用“ __doRequest”。然后将结果传递到parse_packet_soap
,然后解析xml。
答案 2 :(得分:0)
function simpleXML_to_object($obj)
{
$data = new StdClass();
if(
(is_object($obj) && get_class($obj) == 'SimpleXMLElement')
)
{
/*
* Loop through the children
*/
if (count($obj->children()))
{
foreach ($obj as $key => $value)
{
/*
* If this is actually an array, treat it as such.
* This sort of thing is what makes simpleXML a pain to use.
*/
if (count($obj->$key) > 1)
{
if(!isset($data->$key) || !is_array($data->$key))
{
$data->$key = array();
}
array_push($data->$key, simpleXML_to_object($value));
}
else
{
$data->$key = simpleXML_to_object($value);
}
}
}
if (count($obj->attributes()))
{
foreach ($obj->attributes() as $key => $value)
{
$data->$key = (string) $value;
}
}
/*
* If we have no attributes and no children, treat this as a string.
*/
if (count(get_object_vars($data)) == 0)
{
$data = (string) $obj;
}
elseif (strlen( (string) $obj ))
{
$data->value = (string) $obj;
}
}
elseif (is_array($obj))
{
foreach($obj as $key => $value)
{
$data->$key = simpleXML_to_object($value);
}
}
else {
$data = (string) $obj;
}
return $data;
}
答案 3 :(得分:0)
我使用了Alex Blex和gaRex建议来模拟__doRequest方法。 有效。我附上示例代码。
$localXml = file_get_contents(__DIR__ . '/localResponse.xml');
$wsdl = 'https://*******.com/path/to/wsdlV5?WSDL';
$soapClientMock = $this->getMockBuilder(\SoapClient::class)
->setConstructorArgs([$wsdl])
->setMethods(['__doRequest'])
->getMock();
$soapClientMock->expects($this->once())
->method('__doRequest')->will($this->returnValue($localXml));
$result = $soapClientMock->__call('Function', []);