Error in angular unit test cases: TypeError: this.userService.currentUser.subscribe is not a function
Error in angular unit test cases: TypeError: this.userService.currentUser.subscribe is not a function
我在 运行 angular 单元测试用例时遇到此错误:
测试结果
SidebarComponent
× should create
TypeError: this.userService.currentUser.subscribe is not a function
sidebar.component.spec.ts
describe('SidebarComponent', () => {
let fixture: ComponentFixture<SidebarComponent>;
let mockUserService;
beforeEach(() => {
mockUserService = jasmine.createSpyObj(['currentUser']);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [SidebarComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [{ provide: UserService, useValue: mockUserService }]
});
fixture = TestBed.createComponent(SidebarComponent);
});
fit('should create', () => {
mockUserService.currentUser.and.returnValue(of('Here goes an object'));
fixture.detectChanges();
expect(SidebarComponent).toBeTruthy();
});
});
sidebar.component.ts
ngOnInit() {
this.userService.currentUser.subscribe(currentUser => {
// Some code here
});
}
package.json
"devDependencies": {
"@types/jasmine": "2.8.8",
"@types/jasminewd2": "2.0.3",
"@types/node": "9.6.23",
"jasmine-core": "2.99.1",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.2.0",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "2.0.0",
"karma-coverage-istanbul-reporter": "1.4.3",
"karma-jasmine": "2.0.1",
"karma-jasmine-html-reporter": "1.4.0",
"karma-junit-reporter": "1.2.0",
"karma-spec-reporter": "0.0.32",
"protractor": "6.0.0",
"rxjs-tslint": "0.1.7",
}
user.service.ts
@Injectable({ providedIn: 'root'})
export class UserService {
private currentUserSubject = new BehaviorSubject({});
public currentUser: Observable<User> = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());
setUser(user) {
this.currentUserSubject.next({ ...newUser });
}
}
据我所知,要解决这个问题,我们需要在以下语句中使用:
mockUserService.currentUser.and.returnValue(of('Here goes an object'));
其中的是从 'rxjs' 导入的。当我记录 of('Here goes an object') 的值时,它表明它是可观察的。
我该如何解决这个问题?
你可以像那样做你的嘲笑:
export const mockUserService= {
currentUser = {
subscribe() {
return of({
// whatever here
});
}
}
};
该代码创建了一个伪造的服务。您可以在这个虚假服务中添加被测试组件使用的所有函数和成员。
如何使用spyOn
模拟特定的服务方法:
const userService = TestBed.get(UserService);
const mockedResponse = {}; // Modify as per your need
spyOn(userService, 'currentUser').and.callFake(() => {
return of(mockedResponse);
});
这对我有用。
在对这个测试做了一些工作之后,我发现我们不能使用 spyOn(userService, 'currentUser')。原因很明显,currentUser 不是一个函数,而是一个变量,我们在其中分配了一个 observable。 SpyOn 将在此基础上创建一个假函数,但我们需要的是一个可观察的。所以我们可以使用userService.setUser方法来适当设置currentUser的值。
sidebar.component.spec.ts
describe('SidebarComponent', () => {
let component: SidebarComponent;
let fixture: ComponentFixture<SidebarComponent>;
let userService: UserService;
beforeEach(done => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
declarations: [SidebarComponent],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(SidebarComponent);
component = fixture.componentInstance;
userService = TestBed.get(UserService);
userService.setUser(userInfo);
fixture.detectChanges();
done();
});
});
it('should create', done => {
expect(component).toBeTruthy();
done();
});
})
我在 运行 angular 单元测试用例时遇到此错误:
测试结果
SidebarComponent
× should create
TypeError: this.userService.currentUser.subscribe is not a function
sidebar.component.spec.ts
describe('SidebarComponent', () => {
let fixture: ComponentFixture<SidebarComponent>;
let mockUserService;
beforeEach(() => {
mockUserService = jasmine.createSpyObj(['currentUser']);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [SidebarComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [{ provide: UserService, useValue: mockUserService }]
});
fixture = TestBed.createComponent(SidebarComponent);
});
fit('should create', () => {
mockUserService.currentUser.and.returnValue(of('Here goes an object'));
fixture.detectChanges();
expect(SidebarComponent).toBeTruthy();
});
});
sidebar.component.ts
ngOnInit() {
this.userService.currentUser.subscribe(currentUser => {
// Some code here
});
}
package.json
"devDependencies": {
"@types/jasmine": "2.8.8",
"@types/jasminewd2": "2.0.3",
"@types/node": "9.6.23",
"jasmine-core": "2.99.1",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.2.0",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "2.0.0",
"karma-coverage-istanbul-reporter": "1.4.3",
"karma-jasmine": "2.0.1",
"karma-jasmine-html-reporter": "1.4.0",
"karma-junit-reporter": "1.2.0",
"karma-spec-reporter": "0.0.32",
"protractor": "6.0.0",
"rxjs-tslint": "0.1.7",
}
user.service.ts
@Injectable({ providedIn: 'root'})
export class UserService {
private currentUserSubject = new BehaviorSubject({});
public currentUser: Observable<User> = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());
setUser(user) {
this.currentUserSubject.next({ ...newUser });
}
}
据我所知,要解决这个问题,我们需要在以下语句中使用:
mockUserService.currentUser.and.returnValue(of('Here goes an object'));
其中的是从 'rxjs' 导入的。当我记录 of('Here goes an object') 的值时,它表明它是可观察的。
我该如何解决这个问题?
你可以像那样做你的嘲笑:
export const mockUserService= {
currentUser = {
subscribe() {
return of({
// whatever here
});
}
}
};
该代码创建了一个伪造的服务。您可以在这个虚假服务中添加被测试组件使用的所有函数和成员。
如何使用spyOn
模拟特定的服务方法:
const userService = TestBed.get(UserService);
const mockedResponse = {}; // Modify as per your need
spyOn(userService, 'currentUser').and.callFake(() => {
return of(mockedResponse);
});
这对我有用。
在对这个测试做了一些工作之后,我发现我们不能使用 spyOn(userService, 'currentUser')。原因很明显,currentUser 不是一个函数,而是一个变量,我们在其中分配了一个 observable。 SpyOn 将在此基础上创建一个假函数,但我们需要的是一个可观察的。所以我们可以使用userService.setUser方法来适当设置currentUser的值。
sidebar.component.spec.ts
describe('SidebarComponent', () => {
let component: SidebarComponent;
let fixture: ComponentFixture<SidebarComponent>;
let userService: UserService;
beforeEach(done => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule],
declarations: [SidebarComponent],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(SidebarComponent);
component = fixture.componentInstance;
userService = TestBed.get(UserService);
userService.setUser(userInfo);
fixture.detectChanges();
done();
});
});
it('should create', done => {
expect(component).toBeTruthy();
done();
});
})