gpt4 book ai didi

Angular 7 : Mocking FileSaver. 在单元测试中另存为

转载 作者:行者123 更新时间:2023-12-05 06:22:28 29 4
gpt4 key购买 nike

我有一个包含以下部分的 Angular 组件:

my.component.html(节选)

<button pButton
class="download ui-button ui-button-secondary"
(click)="exportFile(logEvent)"
icon="fas fa-file-download">
</button>

my.component.ts(节选)

import {saveAs} from 'file-saver';

exportFile(logEvent: LogEvent) {
saveAs(new Blob([logEvent.details]), 'log-details.txt');
}

这在我的应用程序中非常有效。我现在想在我的单元测试中对此进行测试。在寻找确保调用 saveAs() 的方法时,我偶然发现了两篇 stackoverflow 文章:mocking - Testing FileSaver in Angular 5Do you need spies to test if a function has been called in Jasmine? .基于此,我编写了以下测试:

my.component.spec.ts(摘录)

import * as FileSaver from 'file-saver';

beforeEach(() => {
spyOn(FileSaver, 'saveAs').and.stub();
});

it('should download a file if the download button is clicked', (fakeAsync() => {
// fakeAsync because in my real test, there are httpClient test aspects as well
advance(fixture);

expect(page.downloadButton).toBeDefined();
click(page.downloadButton);
advance(fixture);

expect(FileSaver.saveAs).toHaveBeenCalled();
}));

这两个辅助方法来自 Angular Testing Example :

export function advance(f: ComponentFixture<any>): void {
tick();
f.detectChanges();
}

export const ButtonClickEvents = {
left: {button: 0},
right: {button: 2}
};

export function click(el: DebugElement | HTMLElement, eventObj: any = ButtonClickEvents.left): void {
if (el instanceof HTMLElement) {
el.click();
} else {
el.triggerEventHandler('click', eventObj);
}
}

我的问题是,测试失败,输出如下:

Error: Expected spy saveAs to have been called.

Error: 1 timer(s) still in the queue.

所以看起来 stub 和断言似乎都不起作用。

如果我从 testm 中删除 click() 调用,1 timer(s) still in the queue 错误不再显示,所以我收集到 click( ) 方法起作用并触发真正的 saveAs() 调用——我想用 spy /模拟替换它。

我该如何解决这个问题?


更新,考虑到建议的解决方案:

我。按照 SiddarthPal 的建议将 my.component.spec.ts 中的导入更改为:

import * as FileSaver from 'file-saver';

没有任何区别。测试仍然导致两个断言错误。

二。按照 uminder 的建议将 spy 设置更改为:

spyOn(FileSaver, 'saveAs').and.callFake(() => null);

也没有什么区别。测试仍然导致两个失败的断言。

我试过如下编写 spy 模拟:

spyOn(FileSaver, 'saveAs').and.callFake(() => {
console.log('--- faking saveAs ---');
return null;
});

检查 Karma 服务器的输出,我在任何地方都看不到这个,所以看起来 spy 根本没有捕捉到我的组件对 saveAs() 的调用。

三。 uminder 的替换建议:

click(page.downloadButton);
advance(fixture);

click(page.downloadButton);
flush();

确实会消耗挂起的计时器错误。然而,onyl 隐藏了一个事实,即使用了真正的 saveAs() 调用,而不是 spy /模拟。所以我仍在寻找方法让它发挥作用。

最佳答案

好吧,我现在正在努力解决完全相同的问题。我的 spy 也不工作,它调用真正的 FileSaver 方法。这里的建议也没有解决我的问题。

我认为问题在于,FileSaver 不是适当的 Angular 模块的一部分,它只是从 FileSaver.js 导入的.我在模拟方面遇到了非常相似的问题,在 this 中有所描述。线。Tl;dr:我通过从 Funnelimport 用法切换到声明 FunnelProvider 并将其注入(inject)我的构造函数来解决该问题真正的方法如:

constructor(private funnelProvider: FunnelProvider) {}

然后在规范文件中我能够模拟该提供者。

所以我想出了这两个解决方案:

<强>1。使用 angular-file-saver

我想,好吧,也许有一个 FileSaver.js 包装器库可以为我提供 Angular 服务,然后 is .但是依赖项已经过时了……这可能是个问题。但是从 FileSaver.js 切换到 angular-file-saver 应该是一个简单的改变。

<强>2。为 FileSaver.js 构建您自己的包装器

我现在能想到的唯一其他解决方案是自己将 FileSaver 用法包装到它自己的 Angular 模块中。然后导入该模块并将新构建的 FileSaverService 注入(inject)到您的真实类中。在 spec 文件中,您可以执行以下操作:

describe("MyComponent", () => {

let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;

let fileSaverServiceSpy: jasmine.SpyObj<FileSaverService>;

beforeEach(() => {
fileSaverServiceSpy= jasmine.createSpyObj('FileSaverService', ['saveAs']);

TestBed
.configureTestingModule({
declarations: [
MyComponent
],
providers: [
{ provide: FileSaverService, useValue: fileSaverServiceSpy }
]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});
});

it('saveMyFile() should call FileSaver', () => {
fileSaverServiceSpy.saveAs.and.stub();

MyComponent.saveMyFile("testFileName");

expect(fileSaverServiceSpy.saveAs).toHaveBeenCalled();
});

});

然而,为了让 spy 工作,所有这一切似乎都需要大量工作。

编辑:我正在一个 angular 9 项目上测试它,这些是我的相关依赖项:

"@angular/core": "9.1.12",
"jasmine-core": "3.6.0",
"jasmine-spec-reporter": "6.0.0",
"karma": "5.2.3",
"karma-coverage-istanbul-reporter": "3.0.3",
"karma-firefox-launcher": "^2.0.0",
"karma-jasmine": "4.0.1",
"karma-jasmine-html-reporter": "1.5.4",
"karma-typescript": "5.2.0",

关于Angular 7 : Mocking FileSaver. 在单元测试中另存为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59281306/

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