如何监视作为BehaviorSubject/Observable的服务属性?遇spyOnProperty报错
Hey there, let's break down why you're hitting that error and walk through two solid fixes—including the method-based approach you already thought of!
The Root Cause
That error pops up because spyOnProperty with the 'get' access type expects your user property to be a getter property (defined with the get keyword), but right now your UserService's user is just a regular, plain property. Jasmine can't spy on a getter that doesn't exist, hence the message.
Solution 1: Turn user into a Getter Property
If you want to stick with using spyOnProperty, all you need to do is refactor your UserService to make user a getter. Here's how that would look:
// UserService.ts import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UserService { // Private backing field to hold the user observable internally private _user$: Observable<User> = of(defaultUser); // Getter for the user observable get user(): Observable<User> { return this._user$; } // Optional: Add a method if you need to update the user later updateUser(newUser: User): void { this._user$ = of(newUser); } }
With this change, your original test code will work exactly as you wrote it:
spyOnProperty(userService, 'user', 'get').and.returnValue(Observable.of(adminUser));
Solution 2: Use a Method (Your Proposed Idea)
If you'd rather avoid getters entirely, your plan to switch to a getUser() method is a great alternative. Here's how to implement that:
First, update the UserService to replace the direct property with a method:
// UserService.ts @Injectable({ providedIn: 'root' }) export class UserService { private user$: Observable<User> = of(defaultUser); getUser(): Observable<User> { return this.user$; } }
Next, update your component code to call userService.getUser().subscribe(...) instead of accessing userService.user directly. For testing, you'll spy on the method instead of the property:
spyOn(userService, 'getUser').and.returnValue(Observable.of(adminUser));
Both approaches work perfectly—pick whichever fits your code style better!
内容的提问来源于stack exchange,提问作者Ka Mok

