Angular 茉莉花单元试验的角度模拟法 测试方法

Angular 茉莉花单元试验的角度模拟法 测试方法,angular,unit-testing,jasmine,mocking,karma-jasmine,Angular,Unit Testing,Jasmine,Mocking,Karma Jasmine,我想测试我的方法中是否调用了router.navigate。现在我想用email和passwort来模拟我的服务。register,但不知何故,我无法模拟它 我的规范文件 单元测试 但它仍然让我感到: Expected spy Router.navigate to have been called with [ [ '/completeSignUp' ] ] but it was never called. 您将收到错误,因为带有EmailandPassword spy的注册表未返回承诺。您可

我想测试我的方法中是否调用了
router.navigate
。现在我想用email和passwort来模拟我的
服务。register,但不知何故,我无法模拟它

我的规范文件 单元测试 但它仍然让我感到:

Expected spy Router.navigate to have been called with [ [ '/completeSignUp' ] ] but it was never called.

您将收到错误,因为带有EmailandPassword spy的注册表未返回承诺。您可以使用callFake返回承诺:

(<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.callFake(() => Promise.resolve([]));
(registryStub.registerWithEmailAndPassword)和.callFake(()=>Promise.resolve([]);

此外,承诺是异步的,因此您可能应该使用test和tick、timeout或使用then方法返回对象,而不是承诺。

您将收到错误,因为registerWithEmailAndPassword spy不返回承诺。您可以使用callFake返回承诺:

(<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.callFake(() => Promise.resolve([]));
(registryStub.registerWithEmailAndPassword)和.callFake(()=>Promise.resolve([]);

此外,承诺是异步的,因此您可能应该使用test和tick,或者timeout,或者使用then方法返回对象,而不是Promise。

正如silicon Soul所提到的,您需要明确地模拟
路由器。使用returnvalue导航
Promise,否则它将进入
Promise.reject()
。通过添加
(routerStub.navigate).和.returnValue(Promise.resolve())单元测试应该正常。
最终的单元测试应该如下所示:

  it('should navigate on promise - success', fakeAsync(() => {
    const spy = (<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve());
    (<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.returnValue(Promise.resolve(['test']));
    component.onSubmit({username: 'test', email: 'test', password: 'test', passwordConfirm: 'test', termsAndCondition: true});

    tick();
    expect(spy).toHaveBeenCalledWith(['/completeSignUp']);
  }));
it('应该在promise-success上导航',fakeAsync(()=>{
constspy=(routerStub.navigate).和.returnValue(Promise.resolve());
(registryStub.registerWithEmailAndPassword)和.returnValue(Promise.resolve(['test']);
onSubmit({username:'test',email:'test',password:'test',passwordConfirm:'test',termsAndCondition:true});
勾选();
期望(spy).tohavencalledwith(['/completeSignUp']);
}));

正如silicon Soul所提到的,您需要明确地模拟
路由器。使用返回值导航
promise,否则它将进入
promise.reject()
。通过添加
(routerStub.navigate).和.returnValue(Promise.resolve())单元测试应该正常。
最终的单元测试应该如下所示:

  it('should navigate on promise - success', fakeAsync(() => {
    const spy = (<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve());
    (<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.returnValue(Promise.resolve(['test']));
    component.onSubmit({username: 'test', email: 'test', password: 'test', passwordConfirm: 'test', termsAndCondition: true});

    tick();
    expect(spy).toHaveBeenCalledWith(['/completeSignUp']);
  }));
it('应该在promise-success上导航',fakeAsync(()=>{
constspy=(routerStub.navigate).和.returnValue(Promise.resolve());
(registryStub.registerWithEmailAndPassword)和.returnValue(Promise.resolve(['test']);
onSubmit({username:'test',email:'test',password:'test',passwordConfirm:'test',termsAndCondition:true});
勾选();
期望(spy).tohavencalledwith(['/completeSignUp']);
}));

首先感谢您的回复,但是registerWithEmailAndPassword确实返回了一个承诺。服务中的方法(我想这与问题无关,但是)如下所示:
公共registerWithEmailAndPassword(register:RegisterDataModel):承诺{const successMessages:string[]=[];const errorMessages:string[]=[];返回新承诺(((resolve,reject)=>{this.createUserWithEmailCredentials(register,successMessages,resolve,errorMessages,reject);});}
确定,但您没有调用原始方法。您正在调用存根方法,默认情况下该方法不返回任何内容。使用returnValue也应该有效,但正如前面提到的,承诺是异步的,所以您应该等待或强制勾选。您实际上有一些代码要提供吗?我用fakeAsync
it('should call navigate',fakeAsync(()=>{const spy=(routerStub.navigate).and.stub();(registryStub.registerWithEmailAndPassword)和.returnValue(Promise.resolve(()=>['test']);component.onSubmit尝试了它({username:'test',email:'test',password:'test',termsAndCondition:true});勾选();期望(spy).toHaveBeenCalledWith(['/completeSignUp']);})
但是我得到了一个:msg.forEach不是函数错误…这个单元测试很痛苦…:)抱歉,如果没有完整的代码,就无法提供任何测试内容。fakeAsync代码似乎很好。我假设您得到错误是因为调用了Promise-catch回调且参数不是数组。我注意到了一些事情。Promise.resolve sho无法通过值-Promise.resolve(['test'])。未看到任何代码来模拟router.navigate方法的结果,该方法将由于then调用而导致错误。此外,请验证notificationService没有引发错误。首先,感谢您的回复,但registerWithEmailAndPassword确实返回了服务中该方法的承诺(我想这与问题无关,但是)看起来如下:
public registerWithEmailAndPassword(register:RegisterDataModel):Promise{const successMessages:string[]=[];const errorMessages:string[]=[];return new Promise((解析,拒绝)=>{this.createUserWithEmailCredentials(注册、成功消息、解析、错误消息、拒绝);})
OK,但您没有调用原始方法。您调用的是存根方法,默认情况下不返回任何内容。使用returnValue也应该可以工作,但如前所述,承诺是异步的,所以您应该等待或强制勾选。您真的有一些代码要提供吗?我用fakeAsync
it尝试了您提到的方法('should call navigate',fakeAsync(()=>{const spy=(routerStub.navigate).and.stub();(registryStub.registerWithEmailAndPassword).and.returnValue(Promise.resolve(()=>['test']);component.onSubmit({username:'test',email:'test password:'test:'test',password:'test:'test',',termsAndCondition:true});勾选().toHaveBeenCalledWith(['/completeSignUp'];}))
但是我得到了一个:msg.forEach不是一个函数错误…这个单元测试很痛苦..:)抱歉,没有完整的代码就无法提供任何测试。伪异步代码看起来很好。我假设您是因为
(<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.callFake(() => Promise.resolve([]));
  it('should navigate on promise - success', fakeAsync(() => {
    const spy = (<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve());
    (<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.returnValue(Promise.resolve(['test']));
    component.onSubmit({username: 'test', email: 'test', password: 'test', passwordConfirm: 'test', termsAndCondition: true});

    tick();
    expect(spy).toHaveBeenCalledWith(['/completeSignUp']);
  }));