简体   繁体   English

用诺克嘲笑肥皂服务

[英]Mocking soap services with nock

I'm working on a node app that communicates with soap services, using the foam module to parse json into a valid soap request and back again when the response is received. 我正在与肥皂服务通信的node应用程序上工作,使用foam模块将json解析为有效的肥皂请求,并在收到响应时再次返回。 This all works fine when communicating with the soap services. 与肥皂服务进行通信时,这一切都很好。

The issue I'm having is writing unit tests for this (integration tests work fine). 我遇到的问题是为此编写单元测试(集成测试工作正常)。 I'm using nock to mock the http service and send a reply. 我正在使用nock模拟http服务并发送回复。 This reply does get parsed by foam and then I can make assertions against the response. foam确实会解析此回复,然后我可以对响应做出断言。

So I cannot pass a json object as a reply because foam expects a soap response. 因此,我无法传递json对象作为答复,因为foam需要肥皂响应。 If I try to do this I get the error: 如果我尝试这样做,则会收到错误消息:

Error: Start tag expected, '<' not found

Storing XML in javascript variables is painful and doesn't work (ie wrapping it in quotes and escaping inner quotes isn't valid), so I wanted to put the mocked XML response into a file and pass that as a reply. 将XML存储在javascript变量中是一件很痛苦的事情,并且不起作用(即,将XML括在引号中并转义内部引号无效),因此我想将模拟的XML响应放入文件中并将其作为答复传递。

I've tried reading the file in as a stream 我尝试以流方式读取文件

return fs.createReadStream('response.xml')

...and replying with a file ...然后回复文件

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

Both fail with an error of 两者都失败并显示错误消息

TypeError: Cannot read property 'ObjectReference' of undefined

Here is the XML in the file 这是文件中的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>

The module being tested is 被测试的模块是

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);
            });
        });

    }
};

The assertion is using should-promised 断言是使用should-promised

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

So it looks like the xml parser won't just accept a file (which makes sense). 因此,看起来xml解析器不会仅仅接受一个文件(这很有意义)。 Does the stream not complete before it is tested? 流在测试之前是否未完成?

Can an XML reply be mocked successfully with nock? 能否使用nock成功模拟XML回复?

I also raised this on Github 我也在Github上提出了这个

Following pgte's advice here https://github.com/pgte/nock/issues/326 I was able to get this working by setting the correct headers, replying with an xml string (with escaped quotes). 遵循pgte的建议,在这里https://github.com/pgte/nock/issues/326我能够通过设置正确的标头并以xml字符串(带有转义引号)进行答复来使其正常工作。

From pgte: 从pgte:

It can. 它可以。 I don't know foam well, but I guess you have to set the response content type header (see https://github.com/pgte/nock#specifying-reply-headers ) so that the client can parse the XML correctly. 我不太了解泡沫,但是我想您必须设置响应内容类型标头(请参阅https://github.com/pgte/nock#specifying-reply-headers ),以便客户端可以正确解析XML。

Here's how the working test looks: 这是工作测试的外观:

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;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM