如何模拟 Angular 2 路线?
How do I Mock an Angular 2 route?
我有以下代码...
export class LoginComponent {
userName: string;
password: string;
rememberMe: boolean = false;
constructor( private auth: AuthenticationService,
private router: Router) {
...
}
...
}
我正在尝试进行单元测试,但我的第一次尝试失败了....
beforeEach(() => {
router = new Router();
component = new LoginComponent(authService, router);
});
因为它需要 Router 构造函数的参数。 ...
beforeEach(() => addProviders([
APP_ROUTER_PROVIDERS, // must be first
{provide: APP_BASE_HREF, useValue: '/'}, // must be second
{provide: ActivatedRoute, useClass: Mock},
{provide: Router, useClass: Mock}
]));
但我的依赖项中似乎没有 APP_ROUTER_PROVIDERS
或 Mock
,所以我认为它可能过时了(或者我需要依赖项)。
如何模拟这个?对于我正在进行的测试甚至都没有关系。
对于简单的情况,您可以创建自己的模拟并按值提供它,例如:
describe('whatever', () => {
let mockRouter: any;
...
beforeEach(async(() => {
// create your own mock
mockRouter = jasmine.createSpyObj('Router', ['navigate']);
...
TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [
// provide it by value
{ provide: Router, useValue: mockRouter },
...
],
}).compileComponents();
}));
...
});
这使用了测试平台的依赖注入,而不是试图“new
-up”被测试的class。
有关上下文中的示例,请参见例如one of my projects on GitHub。
我接受了上面的答案,因为它看起来是正确的,但是,我实际上以不同的方式实现它...
describe("Login Component", () => {
let component: LoginComponent;
let authService: AuthenticationService;
let router: Router;
describe("Testing the subscription happens", () => {
beforeEach(() => {
TestBed.configureTestingModule({imports: [RouterTestingModule]});
router = TestBed.get(Router);
authService = new AuthenticationService();
authService.notifications = new Subject();
authService.notifications.subscribe = jasmine.createSpy("SpyToTestNotifications");
});
it("Make sure we try to subscribe to the auth event", () => {
component = new LoginComponent(authService, router);
expect(authService.notifications.subscribe).toHaveBeenCalled();
})
});
});
如您所见,这只需要 beforeEach 中的 2 行...
TestBed.configureTestingModule({imports: [RouterTestingModule]});
router = TestBed.get(Router);
但是,根据@jonrsharpe 的说法,这会做很多事情,因此您无法保证可能会发生其他副作用。但它很快,它很脏而且看起来确实 "work"
这是为每个测试加载查询字符串参数的工作示例。适用于 Angular 2.3.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MyViewerComponent,
...
],
imports: [
HttpModule,
FormsModule,
RouterModule,
...
],
providers: [
{provide: ActivatedRoute, useValue: {queryParams: {test: 111}}},
{provide: MyService, useClass: MyMockService}
]
})
.compileComponents();
}));
我有以下代码...
export class LoginComponent {
userName: string;
password: string;
rememberMe: boolean = false;
constructor( private auth: AuthenticationService,
private router: Router) {
...
}
...
}
我正在尝试进行单元测试,但我的第一次尝试失败了....
beforeEach(() => {
router = new Router();
component = new LoginComponent(authService, router);
});
因为它需要 Router 构造函数的参数。
beforeEach(() => addProviders([
APP_ROUTER_PROVIDERS, // must be first
{provide: APP_BASE_HREF, useValue: '/'}, // must be second
{provide: ActivatedRoute, useClass: Mock},
{provide: Router, useClass: Mock}
]));
但我的依赖项中似乎没有 APP_ROUTER_PROVIDERS
或 Mock
,所以我认为它可能过时了(或者我需要依赖项)。
如何模拟这个?对于我正在进行的测试甚至都没有关系。
对于简单的情况,您可以创建自己的模拟并按值提供它,例如:
describe('whatever', () => {
let mockRouter: any;
...
beforeEach(async(() => {
// create your own mock
mockRouter = jasmine.createSpyObj('Router', ['navigate']);
...
TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [
// provide it by value
{ provide: Router, useValue: mockRouter },
...
],
}).compileComponents();
}));
...
});
这使用了测试平台的依赖注入,而不是试图“new
-up”被测试的class。
有关上下文中的示例,请参见例如one of my projects on GitHub。
我接受了上面的答案,因为它看起来是正确的,但是,我实际上以不同的方式实现它...
describe("Login Component", () => {
let component: LoginComponent;
let authService: AuthenticationService;
let router: Router;
describe("Testing the subscription happens", () => {
beforeEach(() => {
TestBed.configureTestingModule({imports: [RouterTestingModule]});
router = TestBed.get(Router);
authService = new AuthenticationService();
authService.notifications = new Subject();
authService.notifications.subscribe = jasmine.createSpy("SpyToTestNotifications");
});
it("Make sure we try to subscribe to the auth event", () => {
component = new LoginComponent(authService, router);
expect(authService.notifications.subscribe).toHaveBeenCalled();
})
});
});
如您所见,这只需要 beforeEach 中的 2 行...
TestBed.configureTestingModule({imports: [RouterTestingModule]});
router = TestBed.get(Router);
但是,根据@jonrsharpe 的说法,这会做很多事情,因此您无法保证可能会发生其他副作用。但它很快,它很脏而且看起来确实 "work"
这是为每个测试加载查询字符串参数的工作示例。适用于 Angular 2.3.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MyViewerComponent,
...
],
imports: [
HttpModule,
FormsModule,
RouterModule,
...
],
providers: [
{provide: ActivatedRoute, useValue: {queryParams: {test: 111}}},
{provide: MyService, useClass: MyMockService}
]
})
.compileComponents();
}));