Angular2单元测试使用MdlSnackbarService的组件 [英] Angular2 unit testing a component that uses MdlSnackbarService

查看:92
本文介绍了Angular2单元测试使用MdlSnackbarService的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下组件:

import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormGroup, FormControl, Validators} from "@angular/forms";
import {ValidationService} from "../../services/validation.service";
import {Router} from "@angular/router";
import {UsersService} from "../../services/users.service";
import {MdlSnackbarService} from "angular2-mdl";

@Component({
  selector: 'app-signup',
  templateUrl: 'signup.component.html',
  styleUrls: ['signup.component.css'],
  providers: [UsersService]
})
export class SignupComponent implements OnInit {

  form: FormGroup;

  constructor(private fb: FormBuilder,
              private router: Router,
              private usersService: UsersService,
              private mdlSnackbarService: MdlSnackbarService) {
    this.form = fb.group({
      "email": new FormControl("", [Validators.required, ValidationService.emailValidator]),
      "password": new FormControl("", Validators.required)
    });
  }

  ngOnInit() {
  }

  onSignup() {
    if (this.form.valid) {
      let email = this.form.value.email;
      let password = this.form.value.password;
      this.usersService.signup(email, password)
        .then(() => {
          this.router.navigate(['/app/home']);
        })
        .catch(err => {
          this.mdlSnackbarService.showToast(err);
        });
    }

  }

}

我正在尝试为此设置一些单元测试,但是经过了几个小时,我仍然无法运行最简单的测试(由角度CLI自动生成的测试):

And I am trying to setup some unit tests for this, but after quite a few hours I am still unable to run the simplest test (the one autogenerated by the angular CLI):

fdescribe('SignupComponent', () => {
  let component: SignupComponent;
  let fixture: ComponentFixture<SignupComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SignupComponent ],
      providers: [UsersService, AngularFire, MdlDialogOutletService],
      imports: [
        AngularFireModule.initializeApp(firebaseConfig),
        ReactiveFormsModule,
        CommonModule,
        RouterTestingModule.withRoutes([
          // { path: 'settings/:collection/edit/:item', component: DummyComponent }
        ])
      ]
    })
    .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

我收到以下错误:没有MdlSnackbarService的提供者!,所以我要做的是将 MdlSnackbarService 添加到提供程序 configureTestingModule

I get the following error: No provider for MdlSnackbarService! so what I did is adding MdlSnackbarService to the providers configureTestingModule:

providers: [UsersService, AngularFire, MdlDialogOutletService, MdlSnackbarService]

但是,我得到的错误是错误:没有为MdlSnackbarComponent找到组件工厂。您是否将其添加到@ NgModule.entryComponents?
,我不知道如何解决。我没有找到与单元测试有关的任何答案。

but then, the error I've got is Error: No component factory found for MdlSnackbarComponent. Did you add it to @NgModule.entryComponents? which I have no clue how to fix. I haven't found any answer related with unit testing.

有人知道如何解决这个问题吗?

Does anyone knows how to fix this?

推荐答案

您应该对所有这些服务使用模拟,例如 Router UserService MdlSnackbarService 。您希望能够控制这些服务在测试期间的功能。您实际上并不关心服务本身会做什么。重要的是组件如何与它们交互。这就是您要测试的内容。

You should be using mocks for all these services, i.e. the Router, the UserService, and the MdlSnackbarService. You want to be able to control what these services do during the tests. You don't really care what the services do per se. What matters is how the component interacts with them. This is what you want to test.

要设置模拟,您可以执行类似的操作

To set up the mock you can do something like

let router;
let userService;
let snackbar;

beforeEach(() => {
   router = { navigate: jasmine.createSpy('navigate') };
   snackbar = { showToast: jasmine.createSpy('showToast') };
   userService = { signup: (email, pass) => null };

   TestBed.configureTestingModule({
     providers: [
       { provide: Router, useValue: router },
       { provide: UserService, useValue: userService },
       { provide: MdlSnackbarService, useValue: snackbar }
     ]
   });;
});

现在在测试中,您可以控制 UserService 会执行,即返回成功的承诺,或返回错误的承诺。这样,您可以测试组件在两种情况下的反应。

Now in your tests, you can control what the UserService does, i.e. return a successful promise, or return an error promise. This way you can can test how the component reacts to both situations.

it('should navigate on success', async(() => {
  spyOn(userService, 'signup').and.returnValue(Promise.resolve());

  component.signup();

  fixture.whenStable().then(() => {
    expect(router.navigate).toHaveBeenCalledWith(['/app/home']);
  })
}))

it('should show toast on error', async(() => {
  spyOn(userService, 'signup').and.returnValue(Promise.reject('error'));

  component.signup();

  fixture.whenStable().then(() => {
    expect(snackbar.showToast).toHaveBeenCalledWith('error');
  })
}))

基本上,这就是您要测试组件以及它们如何与这些服务交互的方式。

That's basically how you want to test the component and how it interacts with these services.

对于错误,错误:没有找到用于MdlSnackbarComponent。,您需要将该组件添加到测试台 declara中 code>,就像您需要的任何其他组件一样。如果您不想这样做,只需使用相同的选择器制作一个虚拟组件,然后将 that 组件添加到声明。

As far as the error Error: No component factory found for MdlSnackbarComponent., you need to add that component in the test bed declarations just like you would any other component you need. If you don't want to do this, just mock the component by making a dummy component using the same selector, and adding that component to the declarations.

这篇关于Angular2单元测试使用MdlSnackbarService的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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