我是测试的新手,我已经迷路了。
我有一项要测试的服务:
animation.service.ts
...
public constructor(private animationStateService: AnimationStateService,
frameStateService: FrameStateService) {
frameStateService.changedAvailableFrames
.pipe(
...
// Some code in pipe
...
)
).subscribe(() => {
...
// Some code in subscribe
...
}
) }
public start(): void {
if (this.animationStateService.status !== AnimationStatus.Stopped) {
return;
}
this.animationStateService.changeStatus(AnimationStatus.Preloading);
this.preloaderService.preloadAllFrames()
.subscribe(
() => {
this.run();
}
);
}
...
注入的服务:
frame-state.service.ts
@Injectable()
export class FrameStateService {
private changedAvailableFramesSubject: Subject<LayerId> = new Subject();
public changedAvailableFrames: Observable<LayerId> = this.changedAvailableFramesSubject.asObservable();
public constructor() {}
...
animation-state.service.ts
@Injectable()
export class AnimationStateService {
public get status(): AnimationStatus { return this.state.animation.status; }
...
在测试中,我想模拟changedAvailableFrames
中的FrameStateService
和status
中的AnimationStateService
。
我已经做了:
animation.service.spec.ts
describe("AnimationService", () => {
let animationService: SpyObj<AnimationService>;
let animationStateService: SpyObj<AnimationStateService>;
let frameStateService: SpyObj<FrameStateService>;
beforeEach(() => {
const spyFrameStateService = createSpyObj("FrameStateService", [""]);
const spyAnimationStateService = createSpyObj("AnimationStateService", ["changeStatus", "status"]);
TestBed.configureTestingModule({
providers: [
AnimationService,
{provide: FrameService, useValue: spyFrameService},
{provide: AnimationStateService, useValue: spyAnimationStateService},
]
});
animationService = TestBed.get(AnimationService);
animationStateService = TestBed.get(AnimationStateService);
frameStateService = TestBed.get(FrameStateService);
frameStateService.changedAvailableFrames.and.returnValue(of());
});
it("Should call changeStatus", () => {
// Arrange
animationStateService.status.and.returnValue(AnimationStatus.Stopped);
// Act
animationService.start();
// Assert
expect(animationStateService.changeStatus).toHaveBeenCalled();
});
})
我得到的错误:
TypeError: Cannot read property 'pipe' of undefined
TypeError: Cannot read property 'status' of undefined
这时我完全迷路了,我不知道该怎么办。
答案 0 :(得分:2)
const spyFrameStateService = createSpyObj("FrameStateService", [""]);
将创建一个没有方法且没有属性的模拟对象(在这种情况下,第二个参数应消失。如果要使用方法hello
进行模拟,则使其类似于createSpyObj("FrameStateService", ["hello"]);
)。不幸的是,使用createSpyObj
无法创建属性。
但是您需要那里的属性changedAvailableFramesSubject
,对吗?因为它已由您的测试服务订阅。
因此,不要使用createSpyObj
来模拟,而是创建一个简单的对象:
{provide: FrameStateService, useValue: { changedAvailableFramesSubject: new Subject() },
并使其随时随地发出:
const frameStateService = TestBed.get(FrameStateService);
frameStateService.changedAvailableFramesSubject.next('your emitted value');