Angular如何测试需要位置的组件 [英] Angular How to test a Component which requires a Location

查看:73
本文介绍了Angular如何测试需要位置的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,谢谢您的宝贵时间!

我正在学习如何使用Angular,并且对学习如何测试其组件感兴趣.

I am learning how to use Angular and I am interested in learning how to test its Components.

当前,我正在苦苦挣扎,因为我已经完成了Angular页面的英雄之旅"教程,并且正在测试代码以更好地理解它.

Currently I am struggling because I have done the Tour of Heroes tutorial of the Angular page and I am testing the code to understand it better.

重点是我正在测试 hero-details组件,其代码为:

import {Component, OnInit, Input} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {MyHeroService} from '../hero-service/my-hero.service';
import {Location} from '@angular/common';
import {Hero} from '../Hero';

@Component({
  selector: 'app-hero-details',
  templateUrl: './hero-details.component.html',
  styleUrls: ['./hero-details.component.css']
})
export class HeroDetailsComponent implements OnInit {
  @Input() hero: Hero;

  constructor(private route: ActivatedRoute,
              private myHeroService: MyHeroService,
              private location: Location) {
  }

  ngOnInit(): void {
    this.getHero();
  }

  getHero(): void {
    const id = +this.route.snapshot.paramMap.get('id');
    this.myHeroService.getHero(id)
      .subscribe(hero => this.hero = hero);
  }

  goBack(): void {
    this.location.back();
  }
}

我的测试试图证明在创建hero-details组件后调用了getHero():

And my test tries to prove that getHero() is called after creating the hero-details component:

 import {HeroDetailsComponent} from './hero-details.component';
    import {ActivatedRoute} from '@angular/router';
    import {MyHeroService} from '../hero-service/my-hero.service';
    import {MessageService} from '../message.service';
    import {Location} from '@angular/common';
    import {provideLocationStrategy} from '@angular/router/src/router_module';
    import {BrowserPlatformLocation} from '@angular/platform-browser/src/browser/location/browser_platform_location';


    describe('heroDetails', () => {
      it('should call getHero after being created', () => {
        const heroDetailsComponent = new HeroDetailsComponent(new ActivatedRoute(),
          new MyHeroService(new MessageService([])),
          new Location(provideLocationStrategy(new BrowserPlatformLocation(['anyParameter']), '/')));
        spyOn(heroDetailsComponent, 'getHero');

        heroDetailsComponent.ngOnInit();

        expect(heroDetailsComponent.getHero()).toHaveBeenCalled();



      });
    });

我面临的困难是当我尝试创建一个新位置时,这是Hero-datail组件的构造函数的必需参数.

The difficulty I am facing is when I try to create a new Location which is a required parameter for the Hero-datail component's constructor.

第一个Location的参数是PlatformStrategy,因此我使用了提供程序来构建它.此外,提供程序还需要一个看上去像是抽象的PlatformLocation(),因此我选择了唯一可以找到的实现,即BrowserPlatformLocation.

The first Location's parameter is a PlatformStrategy, so then I used the provider to build it. Also, the provider needs a PlatformLocation() which looks like is abstract so then I chose the only implementation I could find which is BrowserPlatformLocation.

所有这些过程之后,测试执行将显示:

After all that process, the test execution says:

浏览器永远不会停止加载套件:

And the browser never ends loading the suite:

这里奇怪的是,IDE确实找到了那些模块,因为我可以导航到它们.

The strange thing here is that the IDE indeed finds those modules because I can navigate to them.

另外,如果我注释掉该测试,该套件也可以很好地工作:

Also if I comment out that test, the suite works well:

另外我还读过:

  1. https://angular.io/api/common/Location
  2. https://www.tektutorialshub.com/location-strategies-angular/
  3. https://angular.io/tutorial/toh-pt5
  1. https://angular.io/api/common/Location
  2. https://www.tektutorialshub.com/location-strategies-angular/
  3. https://angular.io/tutorial/toh-pt5

我该如何以正确的方式对其进行测试?在哪里可以找到有关正确进行此类测试的更多信息?该测试如何轻松模拟该Location参数?

How could I test it in a correct way? Where could I find more information about doing this type of tests properly? How could do this test to mock easily that Location parameter?

感谢您阅读此书

推荐答案

Location是内置服务,您无需实例化它,只需对其进行模拟即可:

Location is a built-in service, you do not need to instantiate it, just mock it:

const locationStub = {
    back: jasmine.createSpy('back')
}

然后在您的providers数组中:

providers: [ ..., {provide: Location, useValue: locationStub} ],

然后在您的测试中只需调用组件goBack方法,然后使用Injector获取服务存根的实例,如下所示:

Then in your test just call the components goBack method, then use the Injector to get the instance of your service stub, like this:

const location = fixture.debugElement.injector.get(Location);

然后测试back函数是否已被调用:

And then just test, that the back function has been called:

expect(location.back).toHaveBeenCalled();

这应该可以解决问题.据我所知,这是处理内置服务的最佳方法,您无需测试它们(Angular团队已经做到了),只需对它们进行模拟并确保已正确调用它们

This should solve the problem. This is, as far as I have seen, the best way to deal with the built-in services, you don't need to test them (Angular team did that already), just mock them and make sure they have been called correctly

这篇关于Angular如何测试需要位置的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆