Angular 如何测试需要位置的组件

Angular How to test a Component which requires a Location(Angular 如何测试需要位置的组件)
本文介绍了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();
  }
}

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

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();



      });
    });

我面临的困难是当我尝试创建一个新的 Location 时,它是 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,所以我用provider来构建它.此外,提供者需要一个看起来很抽象的 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

我怎样才能以正确的方式对其进行测试?我在哪里可以找到有关正确进行此类测试的更多信息?这个测试如何轻松模拟 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 数组中:

Then in your providers array:

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 如何测试需要位置的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)