我正在尝试对Angular服务进行单元测试,该服务使用$ injector注入另一个服务,而不是将服务依赖项作为参数传递。注入的服务是动态的 - 它可能是许多不同服务之一 - 因此它不能作为函数参数传递。
正在测试的服务确定应用程序是在线还是离线,然后使用策略模式进行HTTP调用(我们在线,因此策略是“远程”)或使用本地存储来获取所需数据(我们离线,所以策略是'本地')。它在整个应用程序中的许多场景中使用,因此随后调用的服务和服务方法是动态的。更容易显示简化的相关代码:
class NetworkStrategyService {
constructor (private Offline, private $injector) {}
fulfill (config) {
this.Offline.check()
.then(
() => {
// we're online
const service = $injector.get(config.remote.service);
service[config.remote.method](config.remote.data)
.then(() => {
// Do something with the data
})
},
() => {
// Grab it from local storage
}
)
}
}
我的问题是,因为我无法在单元测试中以正常方式注入服务,所以我不知道如何测试这段代码。我已经模拟了配置,现在我想测试在线和离线时调用正确的服务方法,例如:
it (`calls the remote service, with the remote method, if we're online`, () => {
const remoteMethod = spyOn(config.remote.service, config.remote.method);
// Set up, to get a successful Offline.check() outcome
expect(remoteMethod).toHaveBeenCalledWith(config.remote.data);
});
如何确保模拟服务 服务,并将其传递到我的测试服务中?
答案 0 :(得分:0)
好的,我好像已经解决了它:
let deferred;
let config = {
remote: {
service: 'RemoteService',
method: 'remoteAction',
data: {alpha:1}
},
local: ...
};
beforeEach(() => {
angular.mock.module(($provide) => {
$provide.service(config.remote.service, () => {
return {
[config.remote.method]: () => {}
};
});
});
});
beforeEach(() => {
inject((_$q_, _$rootScope_, _$injector_) => {
$q = _$q_;
$scope = _$rootScope_.$new();
$injector = _$injector_
});
deferred = $q.defer();
});
beforeEach(() => serviceUnderTest = new NetworkStrategyService(Offline, $injector));
it (`calls the remote service, with the remote method, if we're online`, () => {
let dynamicService;
inject((_RemoteService_) => {
dynamicService = _RemoteService_;
});
serviceUnderTest.strategy = 'remote';
const dynamicMethod = spyOn(dynamicService, config.remote.method).and.returnValue(deferred.promise);
serviceUnderTest.makeCall(config);
deferred.resolve();
$scope.$apply();
expect(dynamicMethod).toHaveBeenCalledWith(config.remote.data);
});