I'm trying to do a unit test on a method in my component:
@Component({
selector: 'app-workspaces',
templateUrl: './workspaces.component.html',
styleUrls: ['./workspaces.component.css']
})
export class WorkspacesComponent implements OnInit, AfterViewInit {
@Input() workspaceList: Observable<WorkSpace[]>;
@Output() OnWorkSpaceSelected = new EventEmitter<void>();
@Select(AuthState.getUserData) loadCurrentUser: Observable<User>;
@Select(WorkSpaceState.getWorkSpaces) workspaces: Observable<WorkSpace[]>;
selectedWorkspace: WorkSpace;
constructor(private store: Store, private router: Router, private workspaceController: WorkspacedetailService) { }
ngOnInit() {
this.LoadWorkSpaceFromStorage();
}
/** Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
* Add 'implements AfterViewInit' to the class.
*/
ngAfterViewInit(): void {
this.LoadWorkSpaceFromStorage();
}
private LoadWorkSpaceFromStorage(): void {
const storedWorkspace = JSON.parse(localStorage.getItem('SelectedWorkspace'));
this.NotifyWorkSpaceSelection(storedWorkspace);
}
private SaveWorkSpaceIntoStorage(workspace: WorkSpace): void {
this.selectedWorkspace = workspace;
this.NotifyWorkSpaceSelection(this.selectedWorkspace);
}
private NotifyWorkSpaceSelection(workspace: WorkSpace): void {
// Ensure that workspace on localStorage has the latest updates
this.workspaceController.LoadWorkSpace(workspace.id, (data) => {
localStorage.setItem('SelectedWorkspace', JSON.stringify(data))
sessionStorage.setItem('SelectedWorkspace', JSON.stringify(data));
this.selectedWorkspace = data;
let currentUser = new User();
this.loadCurrentUser.subscribe(userData => currentUser = userData);
this.store.dispatch(new SelectWorkSpace(this.selectedWorkspace));
this.OnWorkSpaceSelected.emit();
}, () => { });
}
OnWorkSpaceSelection(selectedWorkSpace: WorkSpace) {
this.SaveWorkSpaceIntoStorage(selectedWorkSpace);
this.NotifyWorkSpaceSelection(selectedWorkSpace);
// TODO add modal to confirm
this.router.navigateByUrl('/');
}
}
In particular, I want to test the "OnWorkSpaceSelection" method, that basically call the "NotifyWorkSpaceSelection" and wait for a response from the controller.
I'm using Jasmine with ngMocks to make it easier. And this is my test now:
describe('Workspace component unit tests', () => {
let component: WorkspacesComponent;
let fixture: ComponentFixture<WorkspacesComponent>;
let helper = new BaseHelper();
beforeEach(() => {
TestBed.configureTestingModule({
// our component for testing
declarations: [WorkspacesComponent],
providers: [
MockProviders(Store, Router, WorkspacedetailService, LoggingService)
],
imports: [MatMenuModule, TranslateModule.forRoot(), NgxsModule.forRoot([AuthState], {
developmentMode: true,
selectorOptions: { suppressErrors: true }
}), HttpClientTestingModule],
});
});
it('OnWorkSpaceSelection should select workspace', () => {
// arrange
let workspace = helper.BuildEntities<WorkSpace>(new WorkSpace()) as WorkSpace;
workspace.id = -1;
localStorage.setItem('SelectedWorkspace', JSON.stringify(workspace));
MockInstance(WorkspacedetailService, () => ({
// comment the next line to check the failure.
LoadWorkSpace: (workSpaceID: number, successCallback: any, errorCallback: any) => {
if (workSpaceID >= 0) {
const workspace = helper.BuildEntities<WorkSpace>(new WorkSpace()) as WorkSpace;
successCallback(workspace);
}
else {
errorCallback();
}
}
}));
fixture = MockRender(WorkspacesComponent); // Rend service
component = fixture.componentInstance; // Take service istance
Object.defineProperty(component, 'loadCurrentUser', { writable: true });
component.loadCurrentUser = of(new User());
fixture.detectChanges();
// act
workspace.id = 0;
component.OnWorkSpaceSelection(workspace); // Call the method that we want to test
// assert
expect(component.selectedWorkspace).toBeTruthy();
});
});
The problem that I have now, is that I get "TypeError: Cannot read property 'subscribe' of undefined" from the run because the "loadCurrentUser" property, inside "NotifyWorkSpaceSelection" method is undefined.
As you can see, I tried to re-initialize it after the build of the component, but I get the same result. Could you suggest me something to solve this issue?
Thank you very much in advance :)
Aucun commentaire:
Enregistrer un commentaire