typescript 如何对使用Angle中的Router的组件进行单元测试?

sdnqo3pr  于 2022-12-19  发布在  TypeScript
关注(0)|答案(4)|浏览(143)

在Angular 2.0.0中,我正在对使用Router的组件进行单元测试。但是,我收到了“提供的参数与调用目标的任何签名都不匹配。”错误。在spec.ts中的Visual studio代码中,红色突出显示的是新的Router()
正确的语法是什么?
我的代码如下:
spec.ts

  1. import { TestBed, async } from '@angular/core/testing';
  2. import { NavToolComponent } from './nav-tool.component';
  3. import { ComponentComm } from '../../shared/component-comm.service';
  4. import { Router } from '@angular/router';
  5. describe('Component: NavTool', () => {
  6. it('should create an instance', () => {
  7. let component = new NavToolComponent( new ComponentComm(), new Router());
  8. expect(component).toBeTruthy();
  9. });
  10. });

组件构造器

  1. constructor(private componentComm: ComponentComm, private router: Router) {}
nwlls2ji

nwlls2ji1#

您也可以只使用RouterTestingModule和spyOnnavigate函数,如下所示

  1. import { TestBed } from '@angular/core/testing';
  2. import { RouterTestingModule } from '@angular/router/testing';
  3. import { Router } from '@angular/router';
  4. import { MyModule } from './my-module';
  5. import { MyComponent } from './my-component';
  6. describe('something', () => {
  7. let fixture: ComponentFixture<LandingComponent>;
  8. let router: Router;
  9. beforeEach(() => {
  10. TestBed.configureTestingModule({
  11. imports: [
  12. MyModule,
  13. RouterTestingModule.withRoutes([]),
  14. ],
  15. }).compileComponents();
  16. fixture = TestBed.createComponent(MyComponent);
  17. router = TestBed.get(Router); // TestBed.inject(Router) for Angular 9+
  18. });
  19. it('should navigate', () => {
  20. const component = fixture.componentInstance;
  21. const navigateSpy = spyOn(router, 'navigate');
  22. component.goSomewhere();
  23. expect(navigateSpy).toHaveBeenCalledWith(['/expectedUrl']);
  24. });
  25. });
展开查看全部
jw5wzhpr

jw5wzhpr2#

这是因为Route有一些依赖项,它希望传递给它的构造函数。
如果你正在使用Angular组件,你不应该尝试做孤立的测试。你应该使用Angular测试基础设施来准备测试环境。这意味着让Angular创建组件,让它 * 注入 * 所有需要的依赖项,而不是你尝试创建所有的东西。
为了让您开始,您应该有这样的内容

  1. import { TestBed } from '@angular/core/testing';
  2. describe('Component: NavTool', () => {
  3. let mockRouter = {
  4. navigate: jasmine.createSpy('navigate')
  5. };
  6. beforeEach(() => {
  7. TestBed.configureTestingModule({
  8. declarations: [ NavToolComponent ],
  9. providers: [
  10. { provide: Router, useValue: mockRouter },
  11. ComponentComm
  12. ]
  13. });
  14. });
  15. it('should click link', () => {
  16. let fixture = TestBed.createComponent(NavToolComponent);
  17. fixture.detectChanges();
  18. let component: NavToolComponent = fixture.componentInstance;
  19. component.clickLink('home');
  20. expect(mockRouter.navigate).toHaveBeenCalledWith(['/home']);
  21. });
  22. });

或者类似的东西。你使用TestBed从头开始配置一个模块来进行测试。你配置它的方式和@NgModule几乎一样。
这里我们只是在模拟路由器。因为我们只是在进行单元测试,所以我们可能不需要真实的的路由工具。我们只是想确保它是用正确的参数调用的。模拟和spy将能够为我们捕获那个调用。
如果你想使用真实的的路由器,那么你需要使用RouterTestingModule,在那里你可以配置路由。

另请参阅:

展开查看全部
unhi4e5o

unhi4e5o3#

下面是我们在组件控制器中注入Route服务的示例:

  1. import { TestBed, async } from '@angular/core/testing';
  2. import { RouterTestingModule } from '@angular/router/testing'; // Because we inject service in our component
  3. import { Router } from '@angular/router'; // Just if we need to test Route Service functionality
  4. import { AppComponent } from './app.component';
  5. import { DummyLoginLayoutComponent } from '../../../testing/mock.components.spec'; // Because we inject service in your component
  6. describe('AppComponent', () => {
  7. let router: Router; // Just if we need to test Route Service functionality
  8. beforeEach(async(() => {
  9. TestBed.configureTestingModule({
  10. declarations: [
  11. AppComponent,
  12. DummyLoginLayoutComponent // Because we inject service in our component
  13. ],
  14. imports: [
  15. RouterTestingModule.withRoutes([
  16. { path: 'login', component: DummyLoginLayoutComponent },
  17. ]) // Because we inject service in our component
  18. ],
  19. }).compileComponents();
  20. router = TestBed.get(Router); // Just if we need to test Route Service functionality
  21. router.initialNavigation(); // Just if we need to test Route Service functionality
  22. }));
  23. it('should create the app', async(() => {
  24. const fixture = TestBed.createComponent(AppComponent);
  25. const app = fixture.debugElement.componentInstance;
  26. expect(app).toBeTruthy();
  27. }));
  28. });

我们还可以测试其他函数,如navigate()。以防万一:

  1. it('should call eventPage once with /register path if event is instanceof NavigationStart', fakeAsync(() => {
  2. spyOn(analyticService, 'eventPage');
  3. router.navigate(['register'])
  4. .then(() => {
  5. const baseUrl = window.location.origin;
  6. const url = `${baseUrl}/register`;
  7. expect(analyticService.eventPage).toHaveBeenCalledTimes(1);
  8. expect(analyticService.eventPage).toHaveBeenCalledWith(url);
  9. });
  10. }));

包含所有模拟组件的文件(mock.components.specs.ts)

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'home',
  4. template: '<div>Dummy home component</div>',
  5. styleUrls: []
  6. })
  7. export class DummyHomeComponent { }
展开查看全部
j0pj023g

j0pj023g4#

贾斯敏更适合做间谍...

  1. describe('Test using router', () => {
  2. const router = jasmine.createSpyObj('Router', ['navigate']);
  3. ...
  4. beforeEach(async(() => {
  5. TestBed.configureTestingModule({
  6. providers: [ { provide: Router, useValue: router } ],
  7. ...
  8. });
  9. });

相关问题