Given a MenuComponent
@Component({
selector: 'cg-menu',
templateUrl: './menu.component.html',
styleUrls: [ './menu.component.scss' ]
})
export class MenuComponent implements OnInit {
menu: MenuItem[];
isLoggedIn$ = this.authStateService.isLoggedIn.pipe(untilDestroyed(this));
constructor(private readonly authStateService: AuthStateService,
private readonly router: Router) {
}
ngOnInit() {
this.authStateService
.state
.pipe(
untilDestroyed(this),
...some logic...
.subscribe();
}
...some logic...
}
and a AuthStateService
@Injectable({ providedIn: 'root' })
export class AuthStateService {
private readonly state$: Observable<AuthState | null>;
private readonly isLoggedIn$: Observable<boolean | null>;
constructor(private readonly sessionManager: SessionManagerService) {
this.state$ = this.stateTrigger$
.pipe(
...some logic...
shareReplay(1));
this.isLoggedIn$ = this.stateTrigger$
.pipe(
map(state => state !== null),
shareReplay(1));
}
get state(): Observable<AuthState> {
return this.state$;
}
get isLoggedIn(): Observable<boolean> {
return this.isLoggedIn$;
}
...some logic...
}
When I'm trying to run this code, Karma is triggering an error.
describe('MenuComponent', () => {
let component: MenuComponent;
let fixture: ComponentFixture<MenuComponent>;
let authStateServiceSpy;
beforeEach(async(() => {
authStateServiceSpy = jasmine.createSpyObj(
'AuthStateService',
{},
{
state: of(null),
isLoggedIn: of(false)
});
TestBed.configureTestingModule({
declarations: [ MenuComponent ],
imports: [ RouterTestingModule ],
providers: [
{ provide: AuthStateService, useValue: authStateServiceSpy }
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should generate correct menu (expert)', () => {
// The problem is here
spyOnProperty(authStateServiceSpy, 'state', 'get').and.callFake(() => of(stateMock));
expect(component.menu).toEqual([
...something...
]);
});
});
The error is this.
Error: <spyOnProperty> : state is not declared configurable
Usage: spyOnProperty(<object>, <propName>, [accessType])
Error: <spyOnProperty> : state is not declared configurable
Usage: spyOnProperty(<object>, <propName>, [accessType])
at <Jasmine>
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/modules/structure/components/menu/menu.component.spec.ts:55:5)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:364:1)
at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:292:1)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:363:1)
at Zone.run (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:123:1)
at runInTestZone (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:545:1)
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:560:1)
Any idea what I'm doing wrong? Thanks for help.
I guess it's because
AuthStateService
's
state
is a
getter in the class, but
your mock declares it as regular property.
You should declare it as
getter as well.
The issue seems related to using createSpyObj
in conjunction with spyOnProperty
, since it's not a real getter you're trying to spy on.
Looking at your code, there seems to be no reason to use createSpyObj
though, so this might do the trick:
// ...
authStateServiceMock = {
get state() { return of(null) },
get isLoggedIn() { return of(false) },
};
// ...
spyOnProperty(authStateServiceMock, 'state', 'get').and.callFake(() => of(stateMock));
expect(component.menu).toEqual([
...something...
]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.