Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 how to Mock Activated Route Params subscribed

I have a components that gets a value from the params property of a ActivatedRoute.

The components looks like:

......
  constructor(public userRegistration: UserRegistrationService, public userLogin: UserLoginService,
              public router: Router, public route: ActivatedRoute) {
  }

  ngOnInit() {
    this.verificationCode = new FormControl('', [Validators.required]);
    this.confirmationCodeForm = new FormGroup({verificationCode: this.verificationCode});

    //****************************** 
    this.sub = this.route.params.subscribe(params => {
      this.email = params['userId'];
    });
   //******************************
    this.errorMessage = null;
  }
 ......

The test provides an ActivatedRoute as "useValue" that mocks the class. The test looks like:

describe('ConfirmRegistrationComponent', () => {
  let component: ConfirmRegistrationComponent;
  let fixture: ComponentFixture<ConfirmRegistrationComponent>;
  let userRegistrationService: UserRegistrationService;
  let userLoginService: UserLoginService;
  let router: Router;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ReactiveFormsModule, FormsModule, RouterTestingModule, HttpClientModule],
      declarations: [ConfirmRegistrationComponent],
      providers: [UserRegistrationService, UserLoginService, {

        provide: ActivatedRoute,
        useValue: {'params': Observable.from([{userId: 1}])}

      }, ImageService, UserService, CognitoUtil,
        {
          provide: Router, useClass: class {
            navigate = jasmine.createSpy('navigate');
          }
        }]
    }).compileComponents();

    fixture = TestBed.createComponent(ConfirmRegistrationComponent);
    component = fixture.componentInstance;
    userRegistrationService = TestBed.get(UserRegistrationService);
    userLoginService = TestBed.get(UserLoginService);
    spyOn(userLoginService, 'isAuthenticated').and.callFake(function () {

    });
    router = TestBed.get(Router);
    fixture.detectChanges();
    component.ngOnInit();
  }));

  it('should create', () => {
  });
});

When I run the test, I get the next error:

Failed: Cannot read property 'subscribe' of undefined
TypeError: Cannot read property 'subscribe' of undefined
    at new RouterLinkWithHref node_modules/@angular/router/esm5/router.js:6099:1)

Could you help me please? Thanks!

like image 424
AleGallagher Avatar asked Jun 14 '18 04:06

AleGallagher


2 Answers

When using the RouterTestingModule, you should not put a Router provider in the providers collection (either import RouterTestingModule or provide Router, but not both).

Additionally, I don't know if this will help, but I had a related problem in Angular 6 where I had to use this syntax:

providers: [
    { provide: ActivatedRoute, useValue: {
            paramMap: of( convertToParamMap( { userId: 1 } ) )
        }
    }
],

convertToParamMap is in @angular/Router

like image 88
Beartums Avatar answered Sep 28 '22 03:09

Beartums


The solution worked for me was the following (Angular 7 + Jest):

const mockActivatedRoute = {
  snapshot: {
    paramMap: {
      get() { return '1'; }
    }
  }
};

And just use it in providers:

      providers: [
        { provide: ActivatedRoute, useValue: mockActivatedRoute },
      ],
like image 31
kli Avatar answered Sep 28 '22 03:09

kli