我如何模拟Angular 2路线?

时间:2016-11-28 21:01:20

标签: angular karma-jasmine angular2-routing angular2-testing angular2-router3

我有以下代码......

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构造函数的参数。 Here I saw ......

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_PROVIDERSMock,所以我认为它可能是陈旧的(或者我需要依赖项)。

我该如何嘲笑这个?对我正在进行的测试来说,它并不重要。

3 个答案:

答案 0 :(得分:6)

对于一个简单的案例,您可以创建自己的模拟并按值提供,例如:

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 - 向上”测试的类。

有关上下文中的示例,请参阅例如one of my projects on GitHub

答案 1 :(得分:2)

我接受了上述答案,因为它似乎是正确的,但是,我实际上是以不同的方式实现的......

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,这可以做很多事情,因此您无法保证可能发生的其他副作用。但它很快,很脏,而且似乎"工作"

答案 2 :(得分:2)

以下是为每个测试加载查询字符串参数的工作示例。适用于Angular 2.3。

$EmployeesXml = [xml](Get-Content .\employees.xml)

# Locate all <employee> nodes, iterate over them
foreach($EmployeeNode in $EmployeesXml.SelectNodes('//employees/employee')){
    # Create hashtable to hold employee data
    $EmployeeData = @{}
    # Iterate over each child node under <employee>
    $EmployeeNode.ChildNodes |ForEach-Object {
        # Populate employee data based on the node name
        $EmployeeData[$_.Name] = $_.InnerText
    }

    # Create object from collected data
    New-Object psobject -Property $EmployeeData
}