1

我正在开发一个node与soap服务通信的应用程序,使用foam模块将json解析为有效的soap请求,并在收到响应时再次返回。在与肥皂服务通信时,这一切都很好。

我遇到的问题是为此编写单元测试(集成测试工作正常)。我nock用来模拟 http 服务并发送回复。这个回复确实会被解析foam,然后我可以对回复做出断言。

所以我不能传递一个 json 对象作为回复,因为foam需要一个肥皂响应。如果我尝试这样做,我会收到错误:

Error: Start tag expected, '<' not found

将 XML 存储在 javascript 变量中是痛苦的并且不起作用(即用引号括起来并转义内部引号是无效的),所以我想将模拟的 XML 响应放入一个文件并将其作为回复传递。

我尝试将文件作为流读取

return fs.createReadStream('response.xml')

...并用文件回复

.replyWithFile(201, __dirname + 'response.xml');

两者都失败,错误为

TypeError: Cannot read property 'ObjectReference' of undefined

这是文件中的XML

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
    <env:Header></env:Header>
    <env:Body>
        <FLNewIndividualID xmlns='http://www.lagan.com/wsdl/FLTypes'>
            <ObjectType>1</ObjectType>
            <ObjectReference>12345678</ObjectReference>
            <ObjectReference xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:nil='true'/>
            <ObjectReference xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:nil='true'/>
        </FLNewIndividualID>
    </env:Body>
</env:Envelope>

正在测试的模块是

var foam = require('./foam-promise.js');

module.exports = {
    createUserRequest: function(url, operation, action, message, namespace) {
        var actionOp = action + '/actionRequestOp',
            uri = url + '/actionRequest';

        return new Promise(function(resolve, reject) {
            foam.soapRequest(uri, operation, actionOp, message, namespace) 
            .then(function(response) {
                resolve(response.FLNewIndividualID.ObjectReference[0]);
            })
            .catch(function(err) {
                reject(err);
            });
        });

    }
};

断言正在使用should-promised

return myRequest(url, operation, action, data, namespace)
    .should.finally.be.exactly('12345678');

所以看起来 xml 解析器不会只接受一个文件(这是有道理的)。流在测试之前是否未完成?

可以用 nock 成功地模拟 XML 回复吗?

我也在Github上提出了这个

4

1 回答 1

4

在https://github.com/pgte/nock/issues/326遵循 pgte 的建议后,我可以通过设置正确的标头、使用 xml 字符串(带有转义引号)回复来完成这项工作。

来自 pgte:

它可以。我不太了解泡沫,但我想您必须设置响应内容类型标头(请参阅 https://github.com/pgte/nock#specifying-reply-headers),以便客户端可以正确解析 XML。

以下是工作测试的外观:

it('should return a user ID', function(){
    var response = '<env:Envelope xmlns:env=\'http://schemas.xmlsoap.org/soap/envelope/\'><env:Header></env:Header><env:Body><UserReference>12345678</UserReference></env:Body></env:Envelope>'

    nock(url)
        .post('/createUserRequest')
        .reply(201, response, {
                'Content-Type': 'application/xml'
              }
        );

    return createUserRequest(url, operation, action, message, options)
        .should.be.fulfilledWith('12345678');
});

it('should be rejected if the request fails', function() {

    nock(url)
        .post('/createCaseRequest')
        .replyWithError('The request failed');

    return createUserRequest(url, operation, action, message, options)
        .should.be.rejected;
});
于 2015-07-08T12:51:36.357 回答