首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角7:在FileSaver.saveAs中模仿UnitTest

角7:在FileSaver.saveAs中模仿UnitTest
EN

Stack Overflow用户
提问于 2019-12-11 08:09:12
回答 1查看 3.2K关注 0票数 3

我有一个角部件,它包含以下部分:

my.component.html (节选)

代码语言:javascript
复制
<button pButton
    class="download ui-button ui-button-secondary"
    (click)="exportFile(logEvent)"
    icon="fas fa-file-download">
</button>

my.component.ts (节选)

代码语言:javascript
复制
import {saveAs} from 'file-saver';

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

这在我的应用程序中非常有效。我现在想在我的单元测试中测试这个。为了寻找确保已经调用了saveAs()的方法,我偶然发现了两篇堆栈溢出文章:模拟测试角5中的FileSaver你需要间谍来测试是否在茉莉花中调用了一个函数?。基于此,我编写了以下测试:

my.component.spec.ts (节选)

代码语言:javascript
复制
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();
}));

这两个助手方法来自角度测试实例

代码语言:javascript
复制
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);
  }
}

我的问题是,该测试在以下输出中失败:

错误:预期的间谍拯救已经被调用。 错误:1个定时器仍在队列中。

因此,无论是固执还是断言似乎都不起作用。

如果我从我的click()中删除1 timer(s) still in the queue调用,1 timer(s) still in the queue错误就不再显示了,所以我收集到click()方法可以工作,并触发真正的saveAs()调用--我想用间谍/saveAs()替换这个调用。

我怎么才能解决这个问题?

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

I.按照my.component.spec.ts的建议,将SiddarthPal中的进口更改为:

代码语言:javascript
复制
import * as FileSaver from 'file-saver';

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

二.按照反光镜的建议,将间谍设置改为:

代码语言:javascript
复制
spyOn(FileSaver, 'saveAs').and.callFake(() => null);

也无济于事。测试仍然导致两个断言失败。

我试着写了下面的间谍模拟:

代码语言:javascript
复制
spyOn(FileSaver, 'saveAs').and.callFake(() => {
    console.log('--- faking saveAs ---');
    return null;
});

检查Karma Server输出的输出时,我在任何地方都没有看到这种情况,因此间谍似乎根本没有捕捉到组件对saveAs()的调用。

三.发光机建议取代:

代码语言:javascript
复制
click(page.downloadButton);
advance(fixture);

使用

代码语言:javascript
复制
click(page.downloadButton);
flush();

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

EN

回答 1

Stack Overflow用户

发布于 2021-03-29 02:44:57

好吧,我现在正努力解决同样的问题。我的间谍也不工作,它调用真正的FileSaver方法。这里的建议也没有为我解决这个问题。

我认为问题是,FileSaver不是一个合适的角度模块的一部分,它只是从FileSaver.js导入的。我在线程中描述了一个类似的问题。Tl;dr:我解决了这个问题,从FunnelFunnel用法切换到声明FunnelProvider,并将其注入实际方法的构造器中,如下所示:

代码语言:javascript
复制
constructor(private funnelProvider: FunnelProvider) {}

在规范文件中,我能够模拟该提供程序。

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

1.使用 角文件保护程序

我想,好吧,也许有一个FileSaver.js包装库,它为我提供了一个角服务,还有。但是,依赖项是outdated...that,这可能是一个问题。但是从FileSaver.js切换到角文件保护程序应该是一个简单的改变。

2.为FileSaver.js构建自己的包装器

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

代码语言:javascript
复制
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(); 
    });

});

然而,所有这些似乎都是为了让间谍工作而做的大量工作。

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

代码语言:javascript
复制
"@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",
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59281306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档