简体   繁体   English

如何为http请求编写单元测试?

[英]How to write unit test for http request?

I am trying to do an unit test a service in my case 我试图在我的情况下进行单元测试服务

In my test controller 在我的测试控制器中

myService.getItem('/api/toy/' + scope.id).success(
   function(toy) {
       $scope.toy = toys.details;
   }
);

MyService 为MyService

angular.module('toyApp').service('myService', ['$http',
    function($http) {
        var service = {};
        return {
            getItem: function(url) {
                return $http.get(url);
            },
        };
    }
]);

Test file. 测试文件。

describe('toy ctrl', function () {
    var $httpBackend, ctrl, myService;

    beforeEach(module('toyApp'));

    beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_, __myService_) {
        scope = _$rootScope_.$new();
        $httpBackend = _$httpBackend_;
        myService = _myService_;

        ctrl = _$controller_('toyCtrl', {
            $scope: scope
        });      

    }));

    describe('call my service', function() {
        it('should make request when app loads', function() {
            $httpBackend.expectGET('/api/toy/123').respond({id:123, detail:456 });
            myService.getItem('/api/toy/123').then(function(toy){
                expect(scope.toy.detail).toBe(456);
            })
            $httpBackend.flush();   
     })
 })

I am getting 我正进入(状态

Error: Unexpected request: GET /api/toy/123
No more request expected

If I take out $httpBackend.flush() , the error is gone but it won't cover the 如果我取出$httpBackend.flush() ,错误就会消失,但不会覆盖

  function(toy) {
       $scope.toy = toys.details;
   }

part. 部分。 I want to cover the function call and not sure how to do this. 我想覆盖函数调用,不知道如何执行此操作。 Can anyone help me about it? 任何人都可以帮我吗? Thanks a lot 非常感谢

Seems like you are "unit" testing the controller, so you don't have to bring in the service in picture as you just need to test the controller logic. 看起来你是“单元”测试控制器,所以你不必引入图片中的服务,因为你只需要测试控制器逻辑。 You could create a mock service and inject it while creating the controller in your test. 您可以创建模拟服务并在测试中创建控制器时注入它。

Example: 例:

var mockItem = {details:{//somestuff}, id:'1'};// set up a mock object to test against later
//....
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_, _$q_) {
    scope = _$rootScope_.$new();
    $httpBackend = _$httpBackend_;

    //Set up mock
    myService = jasmine.CreateSpyObj('myService', ['getItem']); 
    myService.getItem.and.returnValue($q.when(mockItem ));

    ctrl = _$controller_('toyCtrl', {
        $scope: scope,
        myService: myService //<-- Pass it here
    });      

}));


  //.....Assuming you are making the call when controller is instantiated
  it('should make request when app loads', function() {
     expect(myService.getItem).toHaveBeenCalled();
     //You could also check as below
     //expect(myService.getItem).toHaveBeenCalledWith(expectedidpassedin);
     scope.$digest(); //Resolve $q promise callback
     expect($scope.toy).toEqual(mockItem .details);
  });

If you are specifically unit testing your service alone you could do: 如果您是专门对您的服务进行单元测试,您可以:

it('should make request when app loads', function() {
        var resp;
        $httpBackend.expectGET('/api/toy/123').respond({id:123, detail:456});
        myService.getItem('/api/toy/123').then(function(response){
            resp = response.data;
        });
        $httpBackend.flush();   
        expect(resp.detail).toEqual(456);
 });

In your controller instead of chaining success use then 在你的控制器而不是链接success使用then

 myService.getItem('/api/toy/' + scope.id).then(
   function(response) {
       $scope.toy = response.toys.details;
   });

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

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