我试图在Aurelia测试中模拟一些服务,但是一个是注入模拟,另一个是注入实际服务。我看不出有什么区别。
我的测试规范中有几个服务模拟:
export class MockCommunicationService {
imAmock = true;
get(id: number): Promise<ICommunication> {
return Promise.resolve({} as ICommunication);
}
}
export class MockRoundService {
getRounds(): Promise<IRoundList[]> {
return Promise.resolve([{} as IRoundList]);
}
}
您可以看到我放在那里的imAmock
测试属性,以便稍后查看。
我的测试(在TypeScript中)看起来像这样,主要来自测试中的aurelia hub文档:
describe('Communications', () => {
let component: ComponentTester;
let container: Container;
let viewModel: Communications; // <-- the real type
let service = new MockCommunicationService();
let roundService = new MockRoundService();
beforeEach(() => {
container = new Container();
viewModel = container.get(Communications);
component = StageComponent
.withResources(PLATFORM.moduleName('path/to/real/communications'))
.inView('<communications></communications>')
.boundTo(viewModel);
component.bootstrap(aurelia => {
aurelia.use.standardConfiguration()
.plugin(PLATFORM.moduleName("aurelia-validation"));
aurelia.container.registerInstance(RoundService, roundService);
aurelia.container.registerInstance(CommunicationService, service);
});
});
it('should be mocked', done => {
component.create(bootstrap).then(() => {
expect(viewModel.communicationService.imAmock).toBe(true);
done();
}).catch(e => { console.log(e.toString()) });
});
});
这失败了imAmock未定义。如果我console.log(viewModel.communicationService)
我可以看到真实的通信服务及其所有注入的依赖项(例如http等)
但是,如果我对RoundService
执行完全相同的操作,则会按照您的预期注入上面的模拟。
viewModel本身以相同的方式使用@autoinject
:
@autoinject()
export class Communications {
...
constructor(public readonly communicationService: CommunicationService, public readonly roundService: RoundService,
private readonly bindingEngine: BindingEngine, private readonly eventAggregator: EventAggregator, private readonly animator: CssAnimator,
private readonly validationControllerFactory: ValidationControllerFactory) {
...
}
}
(我让前两个公开,所以我可以在测试中访问它们,但它们通常是私人的)
我能找到的唯一提示是Aurelia DI实现使用键映射(通常是类)来解析实例。如果我以某种方式定义了CommunicationService
两次,那么我可能会为同一个班级获得两个不同的密钥...但我无法看到这将如何发生或如何解决它。
非常感谢您的帮助!
EDIT! 感谢@adam-willden below,我开始考虑如何重新排序注册和第一个container.get调用,我想出了这个:
beforeEach(() => {
container = new Container();
component = StageComponent
.withResources(PLATFORM.moduleName('path/to/real/communications'))
.inView('<communications></communications>')
.boundTo(viewModel);
component.bootstrap(aurelia => {
aurelia.use.standardConfiguration()
.plugin(PLATFORM.moduleName("aurelia-validation"));
aurelia.container.registerInstance(RoundService, roundService);
aurelia.container.registerInstance(CommunicationService, service);
viewModel = aurelia.container.get(Communications);
});
});
它起作用,两种服务现在都是模拟。
EDIT2 我不确定我之前尝试过的是什么,但上面的代码不起作用!所以我回到原点 - 如何将服务注入测试?
答案 0 :(得分:1)
刚刚查看过,在我看来你在注册Mock实例之前从容器中请求了Communications实例。
我没有足够的时间来测试正确的解决方案(如果你提供了一个要点已经为你修改过的那个)。但是,如果您已经使用容器来获取视图模型,那么您是否可以将这些行移到class Whatever(object):
def __init__(self):
self.ap = np.float64(0.0)
self.awx = np.float64(0.0)
self.aex = np.float64(0.0)
self.rhs = np.float64(0.0)
def bc_neumann(self, i,m,nx):
m[0] = int(i)
m[1] = int(i-1)
m[2] = int(i+1)
if i == 0:
m[1] = nx - 1
self.ap = self.ap + self.awx
self.awx = 0.0
if i == nx-1:
m[2] = 0
self.ap = self.ap + self.aex
self.aex = 0.0
return m
w = Whatever()
w.bc_neumann(1, [], 42)
之上以进行制作:
container.get