【问题标题】:Jasmine spy not being called茉莉花间谍没有被称为
【发布时间】:2015-07-30 07:36:47
【问题描述】:

我创建了一个角度服务,我正在测试它没有任何问题,然后当我开始遇到问题时,我开始尝试将依赖项注入测试。

我想确保依赖项中的一个函数已被调用,但它返回未定义。

这是我的服务:

angular.module('enigmaApp.services', [])
    .factory('auth', function($window, $http, SS){
        var auth = {};

        auth.register = function(user){
            return $http.post('/register', user)
            .success(function(data){
                if(data.token){
                    SS.setObj('appToken', data.token);
                }
            });
        };

        return auth;
    });

我的测试:

describe('Auth Service Tests', function () {
  var $httpBackend, auth, defer, registerReqHandler, setObjSpy, SS, SSMock, user;

  beforeEach(module('enigmaApp'));

  beforeEach(function () {    
    // Create spies
    setObjSpy = jasmine.createSpy('setObj');

    SSMock = {
      setObj: setObjSpy
    }

    SS = SSMock;

    module(function ($provide) {
      $provide.value('SS', SSMock);
    });
  });

  beforeEach(inject(function (_$httpBackend_, $injector, $q) {
    $httpBackend = _$httpBackend_; 
    defer = $q.defer();
    registerReqHandler = $httpBackend.when('POST', '/register').respond(defer.promise);
    auth = $injector.get('auth');
  }));

  afterEach(function () {
    $httpBackend.flush();
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  describe('auth.register(user)', function () {
    beforeEach(function () {
      user = {
        email: 'bwayne@wayneenterprise.com',
        first_name: 'Bruce',
        last_name: 'Wyane',
        password: 'password123'
      };
    });

    it('should call SS.setObj on successful registration', function () {
      $httpBackend.expectPOST('/register').respond({ token: 'fakeToken' });
      auth.register(user);
      expect(SS.setObj).toHaveBeenCalled();
    });
  });

当我运行测试时,我得到一个失败的测试,上面写着“Expected spy setObj to have been called”。知道我在这里做错了什么吗?我以为我为 SS.setObj 设置了一个模拟并将其提供给模块,

【问题讨论】:

    标签: angularjs unit-testing karma-jasmine


    【解决方案1】:

    您遇到的一个问题是,您似乎实际上并没有在您的工厂中返回您的 auth 对象:

    angular.module('enigmaApp.services', [])
    .factory('auth', function($window, $http, SS){
        var auth = {};
    
        auth.register = function(user){
            return $http.post('/register', user)
            .success(function(data){
                if(data.token){
                    SS.setObj('appToken', data.token);
                }
            });
        };
    
    
        // need to return auth here...
        return auth;
    });
    

    更新

    将你的刷新调用移动到你的 it 块中

    it('should call SS.setObj on successful registration', function () {
    
      $httpBackend
        .expectPOST('/register')
        .respond({ token: 'fakeToken' });
    
      auth.register(user);
      $httpBackend.flush();
    
      expect(SS.setObj).toHaveBeenCalled();
    });
    

    afterEach 块用于清理。 Jasmine 假设您的测试到那时已经结束,因此您的 flush() 呼叫不会有任何效果。

    【讨论】:

    • 我实际上是通过了,我在这篇文章中删除了一些不相关的代码以保持我的示例简洁,这是被删除的一部分。我已将其添加回我的示例中。
    • 尝试编辑您认为不相关的内容总是很危险的。我们所要做的就是你给我们的。您能否制作一个 plunker 来演示该问题,这样调试起来会容易得多。
    • 看来你在错误的地方调用了flush。您需要将其移动到您的 it 块中。 plnkr.co/edit/CArWtpSpVKKEdgTkFpT4?p=preview
    • 我以前从未使用过 plunker,所以我从您在上一个问题中向我展示的示例中复制了代码。 plnkr.co/edit/5fCTnU28g9D358mGtSi0?p=preview
    • 查看更新的答案。我建议花一些时间使用它。这对于重现错误非常简单且非常有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 2014-01-25
    • 2012-08-15
    相关资源
    最近更新 更多