Javascript 在angular中,通过重新分配属性而不是注册替换服务来模拟服务是否是一种不好的做法?

Javascript 在angular中,通过重新分配属性而不是注册替换服务来模拟服务是否是一种不好的做法?,javascript,angularjs,jasmine,angularjs-service,Javascript,Angularjs,Jasmine,Angularjs Service,给定一个服务someService,该服务返回一个包含3个函数的对象:fn1,fn2,fn3 在大多数情况下,我通过做类似的事情来模拟我的服务: (一) 这样做的好处是,您可以使用此模拟来完成替换someService的任何行为,而且无论服务是否返回函数、对象等,都同样容易 但我发现,通过这样做,我也可以在fn1和fn2上使用间谍服务: (二) 这样做的缺点是,我不认为您可以模拟以这种方式返回函数的服务 编辑:我认为您仍然可以使用服务返回功能,只需使用spyOn该功能 但第二种方法的优点是,如果

给定一个服务
someService
,该服务返回一个包含3个函数的对象:
fn1
fn2
fn3

在大多数情况下,我通过做类似的事情来模拟我的服务:

(一)

这样做的好处是,您可以使用此模拟来完成替换
someService
的任何行为,而且无论服务是否返回函数、对象等,都同样容易

但我发现,通过这样做,我也可以在
fn1
fn2
上使用间谍服务:

(二)

这样做的缺点是,我不认为您可以模拟以这种方式返回函数的服务

编辑:我认为您仍然可以使用服务返回功能,只需使用
spyOn
该功能

但第二种方法的优点是,如果您想模拟所有函数并使用spy,然后只替换需要特殊行为的函数,那么您可以很容易地做到这一点,如(3)所示

(三)



因此,我想知道在单元测试时,使用(2)和(3)中的策略覆盖服务、工厂等是否被视为不好的做法,或者两者都可以吗?

注入实际的服务实例,监视需要模拟的功能如何?这是我发现的最优雅的方式。是的,这将是另一种方式。是的,现在我正在尝试代码,我确实喜欢你的想法@JBNizet监视函数,而不是创建一个新的间谍对象,因为这样你就可以在实际实例上使用callThrough(并在函数上执行其他各种间谍操作)。它感觉不像我建议的那么黑。实际上,我现在一直在尝试使用一个装饰程序向我试图模拟的服务添加间谍,然后返回该服务,它似乎工作得很好,我不认为有任何陷阱。
module(function($provide) {
    var someServiceMock = jasmine.createSpyObj('someService', ['fn1', 'fn2']);
    $provide.factory('someService', function() {
        return someServiceMock;
    });
});

//value of someService: {fn1: fakeSpy, fn2: fakeSpy2}
inject(function($injector){
    var service = $injector.get('someService');

    var someServiceMock = jasmine.createSpyObj('someService', ['fn1', 'fn2']);

    _.assign(service, someServiceMock);
});

//value of someService: {fn1: fakeSpy, fn2: fakeSpy2, fn3: realFn3}
inject(function($injector){
    var service = $injector.get('someService');

    var serviceFns = _.functions(service);

    var someServiceMock = jasmine.createSpyObj('someService', serviceFns);
    _.assign(service, someServiceMock);
});

//value of someService: {fn1: fakeSpy, fn2: fakeSpy2, fn3: fakeSpy3}