【问题标题】:Testing a service function POST response with Jasmine使用 Jasmine 测试服务函数 POST 响应
【发布时间】:2016-01-11 20:54:59
【问题描述】:

我不完全确定如何执行此操作,但我有一个端点 URL,它是用于登录身份验证的 POST 请求。添加请求负载时,您将获得成功的登录凭据或错误。但是,我似乎在获取响应时遇到了问题。

这是我的 spec 文件:

describe('Service: AuthFactory',function(){

    beforeEach(function () {
        module('ui.router');
        module('users');
        module('main');
    });

    var AuthFactory, httpBackend;

    beforeEach(inject(function($httpBackend, $rootScope, $controller, _AuthFactory_){
        httpBackend = $httpBackend;
        AuthFactory = _AuthFactory_;

    }));

    it('Return a POST response from a Service function', function() {
        var url = "http://localhost:3000";
        var dataObj = JSON.stringify({
            inputUser: { user: "TestCase1" },
            inputPass: { password: "TestPass1" }
        });
        httpBackend.expect('POST', url + '/api/AuthService/signIn', dataObj)
            .respond({});

        AuthFactory.signIn(dataObj).success(function(response) {
            console.log(response);
            // outputs Object {}
            // when in reality it should
            // output the response to POST
            // eg: { "login": { "user": "Test_User", "time": 54935934593 }, "outputHead": { "token": asjfjj234kfAd } }
        });

        httpBackend.flush();

        expect(true).toBe(true);
    });
});

这是我的Service

angular.module('users').factory('AuthFactory', ['$http', function($http) {

var AuthFactory = {};

AuthFactory.signIn = function(data) {
    return $http.post('http://127.0.0.1:3000/api/AuthService/signIn', data);
};

AuthFactory.signOut = function(data) {
    return $http.post('http://127.0.0.1:3000/api/AuthService/signOut', data);
};

return AuthFactory;

}]);

当我运行测试时,它(显然)通过了,但 console.log() 输出 Object{}

当我使用像 Postman 这样的 Chrome 扩展程序时。我做了一个示例 POST 请求,返回的响应是登录凭据!那么为什么它可以在 Postman 上运行,但在我的 AngularJS Jasmine 单元测试上却不行呢?

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine


    【解决方案1】:

    这一行就是为什么你得到一个空对象作为你的响应:

    httpBackend.expect('POST', url + '/api/AuthService/signIn', dataObj)
            .respond({});
    

    要给出您想要的响应,只需添加以下内容:

    httpBackend.expect('POST', url + '/api/AuthService/signIn', dataObj)
                .respond({"login": { "user": "Test_User", "time": 54935934593 }, "outputHead": { "token": asjfjj234kfAd }});
    

    请参阅documentation 了解更多信息。

    【讨论】:

    • 我明白了。等等..如果您伪造服务响应...那么您到底在测试什么?我认为这就是重点。
    • 您正在测试您的服务是否以特定方式执行,因此您可以模拟响应以控制测试
    • 因此您可以测试您的服务在返回空对象时以及成功响应和错误响应时的响应方式
    • 单元测试应该测试被测单元,即您案例中的服务。它不应该测试服务器的响应 - 这称为集成测试
    • 如果服务方法有多个参数而不是单个对象怎么办
    【解决方案2】:

    要记住的主要事情是,您是在模拟后端服务请求,而不是实际访问服务。 这是通过以下语句完成的:

    httpBackend.expect('POST', url + '/api/AuthService/signIn', dataObj)
        .respond({});
    

    这说的是一个匹配这个 url 的 POST,用一个空对象伪造一个响应。如果您想伪造一个看起来像您的真实响应的响应,您可以简单地在 .response 函数调用中设置该对象。

    例子:

    .respond({login:myuser,authenticated=true}).
    

    如果您正在尝试测试您的后端 API,您将需要研究其他测试框架,例如量角器;

    【讨论】:

    • 等等..如果你在伪造服务的响应......那么你到底在测试什么?我认为这就是重点......
    • 您正在测试服务是否将帖子发送到正确的 URL。
    【解决方案3】:

    您正在使用 $httpBackend 服务模拟您的后端,这意味着不会有真正的请求,但是当您发布到 url + '/api/AuthService/signIn' 时,您模拟的后端将响应一个空对象 (.respond({})) 您应该使用与您的真实后端返回的相同类型的数据进行响应。要点是,您可以控制要在测试中涵盖哪些情况。因此,您可以为失败或成功的登录编写 API 响应

    如果您在邮递员中发出请求,那将使用您的真实后端,这就是区别

    更多信息: https://docs.angularjs.org/api/ngMock/service/$httpBackend http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      • 2014-09-04
      相关资源
      最近更新 更多