【问题标题】:Angular 2 unit test routerLink click on html elementAngular 2 单元测试 routerLink 点击 html 元素
【发布时间】:2017-11-26 13:44:58
【问题描述】:

我正在尝试使用一些链接测试组件,例如:

<a routerLink="/contact">Contact</a>

另外,我已经尝试查看this question,但并没有解决问题。

当我尝试该问题(下面的代码)提出的解决方案时,我不断收到此错误

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [RouterTestingModule],
        declarations: [FooterComponent],
    }).compileComponents();
}));

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

describe('...', () => {
    it('should navigate to "/contact" when clicking on link', async(inject([Location], (location: Location) => {
        fixture.debugElement.query(By.css('.menu')).children[1].nativeElement.click();
        fixture.detectChanges(); 
        fixture.whenStable().then(() => {
            console.log( location.path() );
        });
    })));
});

没有位置提供者!

然后,如果我尝试设置提供程序:[Location] 我收到此错误:

失败:StaticInjectorError[LocationStrategy]:
StaticInjectorError[LocationStrategy]:
NullInjectorError: 没有 LocationStrategy 的提供者!

我试图监视路由器,如下所示:

spyOn(router, 'navigate');
expect(router.navigate).toHaveBeenCalled();

但它没有通过“从未调用”的测试。

我该如何解决这个问题?

【问题讨论】:

  • 我认为你错过了CommonModule。旁注,这是可以想象的最丑陋的样板代码。
  • @AluanHaddad 它确实解决了错误,但 location.path() 日志始终显示为空白 '' 而不是预期的 url。
  • 我对此一无所知。不过,您的设置看起来很可疑。您应该研究一堆不同的同步和异步初始化逻辑。
  • @AluanHaddad 你有什么建议可以改进吗?我是测试新手。
  • 就我个人而言,我会尽可能避免测试组件,方法是将逻辑放在可以在没有框架入侵的情况下进行测试的服务类或函数中。给定的测试似乎是在锻炼框架,而不是你的代码,所以我认为不需要它。具体来说,没有什么说Router.prototype.navigate 是并且将永远是路由器响应点击routerLink 的方式,但您的测试正在测试这一点。

标签: angular unit-testing


【解决方案1】:

正如 Aluan Haddad 在 cmets 中指出的那样,我在 imports 上丢失了 CommonModules

在那之后,错误消失了,但我无法让它工作。原因是因为我使用的是MockModule,在那里我导入了所有常见的服务、组件、模块等。在测试中使用,包括RouterTestingModule

从常见的MockModule 中删除RouterTestingModule 并将其直接移动到imports,解决了这个问题。

// before
imports: [MockModule],

// after
imports: [RouterTestingModule.withRoutes(routing)],

【讨论】:

  • 我想很多人会觉得这很有帮助。你能解释一下为什么它会这样工作吗?看起来很随意。
【解决方案2】:

由于我搜索了一段时间但找不到答案,因此这是为所有无法通过上述答案解决“预期的间谍......但从未被调用”问题的人。

angular 的 routerLink 指令实际上使用“navigateByUrl”而不是“navigate”进行路由,因此您的间谍必须看起来像这样

spyOn(router, 'navigateByUrl')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 2016-12-29
    • 2018-04-11
    • 2017-06-28
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多