I have file:
@Component({
selector: 'page',
templateUrl: './page.html',
styleUrls: ['./page.scss']
})
export class PageComponent implements OnInit, OnDestroy {
private lts: Igst;
constructor(
private router: Router,
private route: ActivatedRoute,
private dispatcher: Dispatcher
) {
this.dispatcher
.ofType(ProductsPageActions.TILE_UPDATE_STATE)
.pipe(
map((action: ProductsPageActions.St) => action.payload.st),
takeUntil(this.componentDestroyed$)
)
.subscribe((st: Igst) => {
this.lts = st;
}
}
handleTs(st: Igst): void {
this.dispatcher.dispatch(new ProductsPageActions.St({st}));
}
}
And i want to make more test coverage
How can i test coverage this line:
this.lts = st;
?
I tried this:
describe('Testing pageComponent', () => {
let cmp: PageComponent;
let fixture: ComponentFixture<PageComponent>;
let dispatcher: Dispatcher;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{provide: ActivatedRoute, useValue: {params: of({section: 'test'})}},
Dispatcher
]
});
it('should handleTileSelect', () => {
spyOn(dispatcher, 'dispatch');
const payload = {
agrType: 'L',
};
cmp.handleTs(payload); // payload is st
expect(dispatcher.dispatch).toHaveBeenCalledTimes(1); // ok
expect(cmp['lts']).toEqual(payload); // lts is undefined
});
}
Package.json
consist of:
"dependencies": {
"@angular-devkit/schematics": "^13.3.0",
"@angular/animations": "^13.3.0",
"@angular/cdk": "^12.2.13",
"@angular/common": "^13.3.0",
"@angular/compiler": "^13.3.0",
"@angular/core": "^13.3.0",
"@angular/forms": "^13.3.0",
"@angular/localize": "^13.3.0",
"@angular/material": "^12.2.13",
"@angular/material-moment-adapter": "^12.2.13",
"@angular/platform-browser": "^13.3.0",
"@angular/platform-browser-dynamic": "^13.3.0",
"@angular/router": "^13.3.0",
"@auth0/angular-jwt": "^2.0.0",
"@fortawesome/fontawesome-free": "^5.2.0",
"@stomp/ng2-stompjs": "^7.0.0",
"@stomp/stompjs": "^4.0.8",
"@types/lodash": "^4.14.116",
"@types/requirejs": "^2.1.31",
"chokidar": "^3.5.3",
"core-js": "^3.6.5",
"deep-freeze": "0.0.1",
"lodash": "^4.17.11",
"moment": "^2.22.2",
"ng2-cache-service": "^1.1.1",
"ngx-perfect-scrollbar": "^8.0.0",
"reselect": "^3.0.1",
"rxjs": "^6.5.5",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~13.3.0",
"@angular-eslint/builder": "13.1.0",
"@angular-eslint/eslint-plugin": "13.1.0",
"@angular-eslint/eslint-plugin-template": "13.1.0",
"@angular-eslint/schematics": "13.1.0",
"@angular-eslint/template-parser": "13.1.0",
"@angular/cli": "~13.3.0",
"@angular/compiler-cli": "^13.3.0",
"@angular/language-service": "^13.3.0",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^8.10.50",
"@typescript-eslint/eslint-plugin": "5.11.0",
"@typescript-eslint/parser": "5.11.0",
"coa": "2.0.2",
"eslint": "^8.11.0",
"eslint-plugin-jasmine": "^4.1.3",
"eslint-plugin-rxjs": "^5.0.2",
"highlight.js": "^11.5.0",
"husky": "^1.1.3",
"jasmine": "^4.0.2",
"jasmine-core": "^4.0.1",
"jasmine-spec-reporter": "~5.0.0",
"json-server": "^0.17.0",
"karma": "^6.3.17",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "^2.2.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"karma-junit-reporter": "^1.2.0",
"karma-spec-reporter": "^0.0.34",
"ngx-highlightjs": "^4.1.4",
"ts-node": "~7.0.0",
"tslib": "^2.3.1",
"typescript": "~4.5.5"
}
EDIT:
I have added Dispatcher
class:
import {IAction} from './action';
import {filter} from 'rxjs/operators';
import {Observable, Subject} from 'rxjs';
export class Dispatcher extends Subject<IAction> {
dispatch(action: IAction): void {
super.next(action);
}
ofType(type: string): Observable<IAction> {
return this.pipe(filter(action => action.type === type));
}
}
export const ofType = (type: string) => (source: Observable<IAction>) =>
new Observable(observer => {
source
.pipe(
filter((action: IAction) => action.type === type)
).subscribe(
(data) => {
observer.next(data);
},
(err) => {
observer.error(err);
},
() => {
observer.complete();
}
);
});
IAction
:
export interface IAction {
readonly type: string;
readonly reducerId?: string;
payload?: any;
}
Subscribe is asynchronous by the time you are accessing lts
the observable wasn't flushed. Try something like:
describe('Testing pageComponent', () => {
let cmp: PageComponent;
let fixture: ComponentFixture<PageComponent>;
let dispatcher: Dispatcher;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{provide: ActivatedRoute, useValue: {params: of({section: 'test'})}},
Dispatcher
]
});
it('should handleTileSelect', fakeAsync(() => {
//spyOn(dispatcher, 'dispatch'); // remove me
const payload = {
agrType: 'L',
};
cmp.handleTs(payload); // payload is st
// expect(dispatcher.dispatch).toHaveBeenCalledTimes(1); // ok
flush(); // or tick();
expect(cmp['lts']).toEqual(payload); // lts is undefined
}));
}