gpt4 book ai didi

angular - 没有 detectChanges 测试可观察对象失败

转载 作者:太空狗 更新时间:2023-10-29 17:07:10 28 4
gpt4 key购买 nike

我正在复制 Angular 文档的一些示例以提高我对 Angular 单元测试的理解,但当我无法弄清楚发生了什么时,我最终进入了一个简单的测试用例。

这是我的 app.component.ts 文件,当我有一个方法“getQuote”从服务获取报价时。

@Component({...})
export class AppComponent {
errMsg: string;
quote: Observable<string>;

constructor (private twainService: TwainService) {}

getQuote () {
this.quote = this.twainService.getQuote().pipe(
catchError(err => {
this.errMsg = err;
return of('...');
})
);
}
}

然后,我创建了一个测试来验证我的 errMsg 属性是否正确更新,以防我的 twainService.getQuote 方法出错:

describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let component: AppComponent;

let getQuoteSpy;

beforeEach(async(() => {
const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
getQuoteSpy = twainService.getQuote.and.returnValue(of(testQuote));

TestBed.configureTestingModule({
declarations: [
AppComponent
],
providers: [
{ provide: TwainService, useValue: twainService }
]
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.debugElement.componentInstance;
});

it('should get error msg when TwainService fails', async(async () => {
const errMsg = 'TwainService fails';
getQuoteSpy.and.returnValue(throwError(errMsg));

component.getQuote();
await fixture.whenStable();

expect(component.errMsg).toBe(errMsg);
}));
});

但问题来了:这个测试总是失败,而且我看不出哪里出了问题。

四处游玩,我设法发现添加如下所示的“fixture.detectChanges()”使测试有效,但我不明白为什么。我认为 detectChanges 方法仅用于将更改传播到组件 View 。

it('should get error msg when TwainService fails', async(async () => {
const errMsg = 'TwainService fails';
getQuoteSpy.and.returnValue(throwError(errMsg));

component.getQuote();
fixture.detectChanges();
await fixture.whenStable();

expect(component.errMsg).toBe(errMsg);
}));

我测试了 async、fakeAsync,并使用直接发出错误的同步 observable 和异步 observable,结果总是一样的。

如果有人能帮助我了解那里发生了什么:)

最佳答案

我想您只需要在测试中调用 getQuote 方法后订阅您的 quote Observable:

 it('should get error msg when TwainService fails', async(async () => {
const errMsg = 'TwainService fails';
getQuoteSpy.and.returnValue(throwError(errMsg));

component.getQuote();
component.quote.subscribe();
await fixture.whenStable();

expect(component.errMsg).toBe(errMsg);
}));

因此,当您在测试中调用 component.getQuote() 时 - 它只是将 this.quote 属性设置为“冷”可观察对象,以便看到 catchError 被触发,你必须订阅 Observable。这将运行它,最终你会根据你的模拟数据 throwError(errMsg) 得到一个错误。

编辑

根据你问题的第二部分:

Playing around, I managed to find that adding a "fixture.detectChanges()" like the following was making the test works, but I don't understand why.

我也已经弄清楚了,很可能您在组件模板的某处使用了 async 管道:{{ quote |异步}}。在引擎盖下,angular 的异步管道订阅了一个 quote Observable 并返回它发出的最新值。这就是为什么我们需要调用 detectChanges 方法,在此之后 - 异步管道将开始订阅 quote Observable(测试将按预期进行)。在这种情况下,我们不需要手动订阅 quote Observable(异步管道会处理它)。是的 - 你是对的:我认为 detectChanges 方法仅用于将更改传播到组件 View

您可以在 stackblitz example 中测试这两个示例.希望这会有所帮助:)

关于angular - 没有 detectChanges 测试可观察对象失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51976075/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com