如何进行单元测试&x27;导航';在Angular中使用查询参数?

如何进行单元测试&x27;导航';在Angular中使用查询参数?,angular,unit-testing,karma-jasmine,Angular,Unit Testing,Karma Jasmine,这是我在组件中的方法 editThis(id) { this.router.navigate(['/categories/edit'], { queryParams: { id: id } }); } 这是我的单元测试用例 fit('should call navigate with correct params', () => { component.editThis("5c7d5fde213e25232864dbe0"); expect(new Mock

这是我在组件中的方法

 editThis(id) {
    this.router.navigate(['/categories/edit'], { queryParams: { id: id } });
  }
这是我的单元测试用例

fit('should call navigate with correct params', () => {
    component.editThis("5c7d5fde213e25232864dbe0");
    expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });
  });
这是模拟路由器

class MockRouter {
  navigateByUrl(url: string) { return url; }
  navigate = jasmine.createSpy('navigate');

}
我得到了这个错误

应使用[['/categories/edit'调用spy navigate ],对象({queryParams:Object({id:'5c7d5fde213e25232864dbe0'})}) ]但从来没有人打过电话

你能给我推荐一种测试方法吗

完整的测试代码

import { FacadeService } from './../../../services/facade.service';
import { HttpClientModule } from '@angular/common/http';
import { AngularFontAwesomeModule } from 'angular-font-awesome';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { CategoriesViewComponent } from './categories-view.component';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable, of } from 'rxjs';
import { Router } from '@angular/router';

var allCategories = [

  {
    "_id": "5c7d5fde213e25232864dbe0",
    "name": "Politics",
    "updatedAt": "2019-03-04T17:26:54.262Z",
    "createdAt": "2019-03-04T17:26:54.262Z",
    "__v": 0
  }
];

class MockRouter {
  navigateByUrl(url: string) { return url; }
  navigate = jasmine.createSpy('navigate');

}

class MockedFacadeService {
  getUserDataFromLocalStorage() {
    return false;
  }
  getGuestPermissionsFromLocalStorage() {
    return { "comments": { "create": false, "read": true, "update": false, "deleteAny": false, "delete": false }, "post": { "create": false, "read": true, "update": false, "delete": false, "like": false, "dislike": false }, "category": { "create": false, "read": true, "update": false, "delete": false } };
  }
  getCategories() {
    return of(allCategories);
  }
}

describe('CategoriesViewComponent', () => {
  let component: CategoriesViewComponent;
  let fixture: ComponentFixture<CategoriesViewComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AngularFontAwesomeModule, RouterTestingModule, HttpClientModule],
      declarations: [CategoriesViewComponent],
      providers: [{ provide: FacadeService, useClass: MockedFacadeService },
      { provide: Router, useClass: MockRouter }]
    })
      .compileComponents();
  }));

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

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

  fit('should call navigate with correct params', () => {
    component.editThis("5c7d5fde213e25232864dbe0");
    expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });
  });

});
从'/../../../../services/facade.service'导入{FacadeService};
从'@angular/common/http'导入{HttpClientModule};
从“AngularFontAwesomeModule”导入{AngularFontAwesomeModule};
从“@angular/core/testing”导入{async,ComponentFixture,TestBed};
从“./categories view.component”导入{categories视图组件};
从“@angular/router/testing”导入{RouterTestingModule};
从'rxjs'导入{可观察的};
从'@angular/Router'导入{Router};
var allCategories=[
{
“_id”:“5c7d5fde213e25232864dbe0”,
“名称”:“政治”,
“更新日期”:“2019-03-04T17:26:54.262Z”,
“createdAt”:“2019-03-04T17:26:54.262Z”,
“_v”:0
}
];
类模拟路由器{
navigateByUrl(url:string){返回url;}
navigate=jasmine.createSpy('navigate');
}
类MockedFacadeService{
getUserDataFromLocalStorage(){
返回false;
}
getGuestPermissionsFromLocalStorage(){
返回{“评论”:{“创建”:false,“读取”:true,“更新”:false,“删除”:false},“发布”:{“创建”:false,“读取”:true,“更新”:false,“删除”:false,“喜欢”:false,“不喜欢”:false}”,类别:{“创建”:false,“读取”:true,“更新”:false,“删除”:false};
}
getCategories(){
返回(所有类别);
}
}
描述('CategoriesViewComponent',()=>{
let组件:CategoriesViewComponent;
let夹具:组件夹具;
beforeach(异步(()=>{
TestBed.configureTestingModule({
导入:[AngularFontAwesomeModule,RouterTestingModule,HttpClientModule],
声明:[CategoriesViewComponent],
提供者:[{提供:FacadeService,useClass:MockedFacadeService},
{提供:路由器,useClass:MockRouter}]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(CategoriesViewComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
拟合('应创建',()=>{
expect(component.toBeTruthy();
});
fit('应使用正确的参数调用导航',()=>{
编辑此(“5c7d5fde213e25232864dbe0”);
expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit']),{queryParams:{id:{5c7d5fde213e25232864dbe0});
});
});

路由器已经有一个可以使用的模拟

更改您的线路:

expect(new MockRouter().navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });
对下列事项:

expect(TestBed.get(Router).navigate).toHaveBeenCalledWith(['/categories/edit'], { queryParams: { id: "5c7d5fde213e25232864dbe0" } });
这将获得在测试床中实例化的实际路由器对象


我希望这有帮助。

您能提供完整的测试配置吗?您的测试代码不可能调用您在测试中创建的新对象
new MockRouter()
上的方法。它在另一个对象上调用此方法。您需要在被测组件中注入模拟路由器,然后运行代码,然后测试注入的模拟路由器是否已被调用。或者您需要获取组件使用的实际路由器的引用,对其进行监视,运行代码,然后验证是否调用了被监视的方法。当然,expect将始终失败,您正在其上实例化一个新的模拟路由器…请参阅上载的整个测试文件。