2015-11-24 2 views
1

Я сделал чрезвычайно простой сервис, чтобы проверить мое здравомыслие, когда дело доходит до тестирования. Вот оно:Ожидающая функция, которая будет вызываться на очень простом сервисе

(function() { 
    'use strict'; 
    angular 
     .module('app') 
     .service('TestService', TestService); 

    function TestService() { 
     function foo() { 
      bar(); 
     } 
     function bar() { 
      console.log('Hello world!'); 
     } 
     return { 
      foo: foo, 
      bar: bar 
     }; 
    } 
}()); 

Так что ничего сложного здесь - Foo() вызывает бар(), который выводит простое сообщение «Hello World» на консоль. Мой тест для этого выглядит следующим образом:

(function() { 
    'use strict'; 
    fdescribe('test.service',function() { 
     var testService; 
     beforeEach(module('app')); 
     beforeEach(inject(function(_TestService_) { 
      testService = _TestService_; 
     })); 

     describe('setup',function() { 
      it('should get the testService',function() { 
       expect(testService).not.toBe(undefined); 
      }); 
     }); 
     describe('foo()',function() { 
      fit('should call bar',function() { 
       spyOn(testService,'bar'); 
       testService.foo(); 
       expect(testService.bar).toHaveBeenCalled(); 
      }); 
     }); 
    }); 
}()); 

Все, что я делаю здесь проверяя обув вызывает бар в обычном методе то есть шпионаж в баре. Но это дает мне ошибку:

Expected spy bar to have been called 

Я потянув меня за волосы, пытаясь понять это, так как это не может быть что-то сложно - Что я принципиально делаю не так?

Спасибо!

+0

одна вещь, которую я мог бы подозревать, что, когда вы пользователя .Service(), вы не должны возвращать объект, в противном случае использовать завод как angular.module («ABC») завод() –

+0

Почему у вас есть подчеркивания по обе стороны от '_TestService_'? Мне никогда не приходилось делать что-либо подобное в моих тестах. – HankScorpio

+1

@HankScorpio для удобства и ремонтопригодности http://stackoverflow.com/a/15318137/1230663 – br3w5

ответ

1

Я думаю, что я вижу, в чем проблема. Когда вы шпионите за testService, 'bar', жасмин заменит свойство «bar» на testService со шпионом, однако внутри вашего сервиса foo() не имеет ссылки на объект testService, поэтому он никогда не может назвать этого шпиона.

Попробуйте это:.

(function() { 
    'use strict'; 
    angular 
     .module('app') 
     .service('TestService', TestService); 

    function TestService() { 
     var service = {}; 
     service.foo = function() { 
      service.bar(); 
     }; 
     service.bar = function() { 
      console.log('Hello world!'); 
     }; 
     return service; 
    } 
}()); 
+0

Это исправить, но я не действительно понимаю, почему существуют две разные ссылки - наверняка шпионы должны ссылаться на функцию на testService, а не на создание собственной самостоятельной ссылки? – Katana24

+0

Рассмотрите это: создайте функцию 'function foo() {...}' и 2 объекта, каждая из которых ссылается на 'var a = {beep: foo}; var b = {beep: foo}; '. Затем сделайте следующее: 'a.beep = someOtherFunction;' << Вот что делает жасмин. Он не изменит 'b.beep' на' someOtherFunction', потому что он не может. Нет никакого способа, чтобы он знал о других ссылках на 'foo', поэтому все остальное, что ссылается на' foo', останется неизменным. Даже если все другие ссылки на 'foo' заменяются на что-то еще, функция все равно будет существовать в памяти, потому что' b' все еще ссылается на нее. Это имеет смысл? – HankScorpio

+0

Чтобы быть понятным, 'testService' в вашем тесте относится к объекту, который вы создали в своей возвращаемой строке' return {...}; '. Он не относится к методу 'TestService()'. 'TestService' не имеет свойства' foo' или 'bar'. – HankScorpio

Смежные вопросы