带路由器的角度2测试

Bea*_*341 3 karma-jasmine angular2-routing angular2-testing angular

我有一个组件,当用户登录它时,路由到一个名为的网址/dashboard我正在努力弄清楚为什么我会收到以下错误.

cannot read property 'args' of undefined
Run Code Online (Sandbox Code Playgroud)

我一直在关注路由器测试的官方文档https://angular.io/docs/ts/latest/guide/testing.html#!#routed-component, 但它似乎没有帮助.我的一半问题是我不太了解文档中的所有代码.这是我对路线的单元测试

 beforeEach(async(()=>{

      class AuthStub{
        private loggedin: boolean = false;
            login(){
              return this.loggedin = true;

            }
      };

      class RouterStub{
        navigateByUrl(url:string){return url;}
      }

    TestBed.configureTestingModule({
      declarations: [ HomePageContentComponent ],
      providers:[
        {provide: Auth, useClass:AuthStub},
        {provide: Router, useClass: RouterStub}
        ]
    })
    .compileComponents()
  }));

  beforeEach(()=>{

      fixture = TestBed.createComponent(HomePageContentComponent);
      comp = fixture.componentInstance;

      de = fixture.debugElement.query(By.css('.loginbtn'));
      el = de.nativeElement;
      fixture.detectChanges();

    });

    it('Should log in and navigate to dashboard', inject([Router],(router:Router)=>{

      const spy = spyOn(router, 'navigateByUrl');

      el.click();

      const navArgs = spy.calls.first().args[0];

      expect(navArgs).toBe('/dashboard');

    }))      
}); 
Run Code Online (Sandbox Code Playgroud)

所以我的问题是这行代码是做什么的......

const navArgs = spy.calls.first().args[0];
Run Code Online (Sandbox Code Playgroud)

以及如何解决我的问题?

服务已添加

@Injectable()
export class Auth { 
    lock = new Auth0Lock('fakefakefakefakefake', 'fake.auth0.com', {
         additionalSignUpFields: [{
            name: "address",                              
            placeholder: "enter your address"
        }],
        theme: {
            primaryColor:"#b3b3b3",
        },
         languageDictionary: {
            title: "FAKE"
        }
    });

    userProfile: any;

    constructor(private router: Router) {
        this.userProfile = JSON.parse(localStorage.getItem('profile'));

        this.lock.on("authenticated", (authResult) => {
            localStorage.setItem('id_token', authResult.idToken);

            this.lock.getProfile(authResult.idToken, (error, profile) => {
                if (error) {

                    alert(error);
                    return;
                }

                profile.user_metadata = profile.user_metadata || {};
                localStorage.setItem('profile', JSON.stringify(profile));
                this.userProfile = profile;
            });
            this.router.navigate(['/dashboard']);
        });
    }

    public login(){
        this.lock.show();

    };

    public authenticated() {
        return tokenNotExpired();
    };

    public logout() {
        localStorage.removeItem('id_token');
        localStorage.removeItem('profile');
        this.router.navigate(['/logout']);
    };
}
Run Code Online (Sandbox Code Playgroud)

yur*_*zui 5

假设您有以下组件:

@Component({
  selector: 'home-comp',
  template: `<button (click)="login()" class="loginbtn">Login</button>
  `
})
export class HomePageContentComponent {
  constructor(private auth: Auth, private router: Router) { }

  login() {
    this.router.navigateByUrl(`/dashboard`);
  }
}
Run Code Online (Sandbox Code Playgroud)

Router使用模拟版本替换真实版本后的测试中:

{ provide: Router, useClass: RouterStub }
Run Code Online (Sandbox Code Playgroud)

在你的情况下:

it('Should log in and navigate to dashboard', inject([Router],(router:Router)=>{
Run Code Online (Sandbox Code Playgroud)

router将是的例子RouterStub.

然后你监视navigateByUrl方法,看看它被调用了多少次

const spy = spyOn(router, 'navigateByUrl');
Run Code Online (Sandbox Code Playgroud)

所以当你点击.loginbtn按钮router.navigateByUrl正在运行时(参见上面的组件)并spy增加calls一些信息(例如,所谓的参数)

最后在这一行

const navArgs = spy.calls.first().args[0];
Run Code Online (Sandbox Code Playgroud)

预计您的router.navigateByUrl方法至少被调用一次然后从第一次调用获得传递参数.

这是工作实例

可能你在某个地方出了问题并且router.navigateByUrl没有被执行.