【问题标题】:Testing Initialization of AngularJS Service with Mocks使用 Mocks 测试 AngularJS 服务的初始化
【发布时间】:2015-12-04 07:56:59
【问题描述】:

我正在尝试测试 Angular 服务在初始化时响应它从另一个服务获得的值的方式,但我很难找到一种不笨拙的方法......更不用说一种有效的方法了.

我要测试的服务看起来像这样:

angular.module('myApp')
  .service('myService', function (Auth, DataGrabber) {
    var self = this;

    this.initialize = function () {
       this.user = Auth.getUser();

       if (!this.user.name) {
         DataGrabber.grabName();
       }

       if (!this.user.birthday) {
         DataGrabber.grabBirthday();
       }
    }

    this.initialize();
  })

这是我尝试测试的不太顺利的方式:

describe('myService', function () {
   var myService;
   var dataGrabberMock;
   var authMock;
   var grabbedName;
   var grabbedBirthday;


   beforeEach(function () {
     module('myApp')
   })

   beforeEach(function() {
     grabbedName = false;
     grabbedBirthday = false;

     authMock = {
       getUser: function () {
         return { 
                  name: 'Bob',
                  birthday: 'Feb 22'
                }
       }
     }

     dataGrabberMock = {
       grabName: function () {
          grabbedName = true;
       },
       grabBirthday: function () {
          grabbedBirthday = true;
       }
     }

     module(function ($provide) {
       $provide.value('Auth', authMock);
       $provide.value('DataGrabber', dataGrabberMock);
     })
   })

   it ('just gets info if all data is present', function () {
     inject(function($injector) {
       myService = $injector.get('myService');
       expect(myService.user.name).toBe('Bob');
       expect(myService.user.birthday).toBe('Feb 22');
     });
   });

   it ('gets info if name is missing', function () {
     // how do I stub the new user response here? 
   })

   it ('calls birthdayGetter if birthday is missing', function () {
     // here too?
   })
})

更改 authMock 为每个测试提供的值的最简洁方法是什么?

我尝试了无数种不同的 inject()、$injector、$provide 和 spyOn() 组合。我终于通过设置存根和间谍并在测试中显式调用 myService.initialize() 让它工作了,但是初始化代码为每个测试运行两次,感觉不对。

我是角度测试的新手,所以作为一个新手,我肯定会忽略一种更好的方法。

谢谢!

【问题讨论】:

    标签: angularjs unit-testing jasmine angular-mock


    【解决方案1】:

    dataGrabbe的赋值有错别字rMock

    要更改 authMock 的值,您可以创建一个单独的方法来设置模拟和一个注入服务的方法,并在测试中调用两者。

    beforeEach(function () {
      grabbedName = false;
      grabbedBirthday = false;
    
      dataGrabberMock = {
        grabName: function () {
          grabbedName = true;
        },
        grabBirthday: function () {
          grabbedBirthday = true;
        }
      };
    
      spyOn(dataGrabberMock, 'grabName');
      spyOn(dataGrabberMock, 'grabBirthday');
    
      module(function ($provide) {
        $provide.value('Auth', authMock);
        $provide.value('DataGrabber', dataGrabberMock);
      });
    });
    
    var authMock;
    
    function setupAuthMock(name, birthday){
      authMock = {
        getUser: function () {
          return {
            name: name,
            birthday: birthday
          };
        }
      };
    }
    
    function setupAuthMockWithoutName(birthday){
      authMock = {
        getUser: function () {
          return {
            birthday: birthday
          };
        }
      };
    }
    
    function setupAuthMockWithoutBirthday(name){
      authMock = {
        getUser: function () {
          return {
            name: name
          };
        }
      };
    }
    
    function setupService() {
      inject(function ($injector) {
        myService = $injector.get('myService');
      });
    }
    
    it('just gets info if all data is present', function () {
      setupAuthMock('Bob', 'Feb 22');
      setupService();
      expect(myService.user.name).toBe('Bob');
      expect(myService.user.birthday).toBe('Feb 22');
    });
    
    it('gets info if name is missing', function () {    
      setupAuthMockWithoutName('Feb 30');
      setupService();
      expect(dataGrabberMock.grabName).toHaveBeenCalled();
    });
    
    it('calls birthdayGetter if birthday is missing', function () {
      setupAuthMockWithoutBirthday('Bob');
      setupService();
      expect(dataGrabberMock.grabBirthday).toHaveBeenCalled();
    });
    

    【讨论】:

    • 谢谢!我最终使用了一个稍微干燥的版本。这真的让我走上了正轨。
    【解决方案2】:

    我又想了想,我认为使用单独的描述块而不是使用单独的方法更简洁。

    describe('myService', function () {
      var myService;
      var dataGrabberMock;
      var authMock;
      var grabbedName;
      var grabbedBirthday;
    
      beforeEach(function () {
        module('myApp');
      });
    
      beforeEach(function () {
        grabbedName = false;
        grabbedBirthday = false;
    
        dataGrabberMock = {
          grabName: function () {
            grabbedName = true;
          },
          grabBirthday: function () {
            grabbedBirthday = true;
          }
        };
    
        spyOn(dataGrabberMock, 'grabName');
        spyOn(dataGrabberMock, 'grabBirthday');
    
        module(function ($provide) {
          $provide.value('Auth', authMock);
          $provide.value('DataGrabber', dataGrabberMock);
        });
      });
    
      describe('when all data is present', function () {
        beforeEach(function () {
          authMock = {
            getUser: function () {
              return {
                name: 'Bob',
                birthday: 'Feb 22'
              };
            }
          };
        });
    
        beforeEach(function () {
          inject(function ($injector) {
            myService = $injector.get('myService');
          });
        });
    
        it('just gets info', function () {
          expect(myService.user.name).toBe('Bob');
          expect(myService.user.birthday).toBe('Feb 22');
        });
      });
    
      describe('when name is missing', function () {
        beforeEach(function () {
          authMock = {
            getUser: function () {
              return {
                birthday: 'Feb 22'
              };
            }
          };
        });
    
        beforeEach(function () {
          inject(function ($injector) {
            myService = $injector.get('myService');
          });
        });
    
        it('gets info', function () {
          expect(dataGrabberMock.grabName).toHaveBeenCalled();
        });
      });
    
      describe('when birthday is missing', function () {
        beforeEach(function () {
          authMock = {
            getUser: function () {
              return {
                name: 'Bob',
              };
            }
          };
        });
    
        beforeEach(function () {
          inject(function ($injector) {
            myService = $injector.get('myService');
          });
        });
    
        it('calls birthdayGetter', function () {
          expect(dataGrabberMock.grabBirthday).toHaveBeenCalled();
        });
      });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 2013-04-23
      • 1970-01-01
      • 2015-10-28
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多