在Jamine上测试对订阅方法的调用(隔离测试)



我尝试在订阅者内部测试对方法的调用,但我不能。每当我调用具有订阅的方法时,控制台都会向我发送错误"error: Expected spy saveMug to have been called"。reContent方法也会失败。

我的测试应该是隔离的,所以我不能使用夹具或试验台。

这是我的组件代码

@Component({
selector: "app-mug",
templateUrl: "./mug.component.html",
styleUrls: ["./mug.component.scss"],
})
export class MugComponent implements OnInit
{
public mug: Mug= new Mug();
constructor(
public constants: Constants,
public mugService: mugService,
private messageService: MessageService,
public route: ActivatedRoute,
public router: Router,
) {
super(constants, route);
}
ngOnInit() {}
public saveMug(previous?: boolean): void {
const sub = this.mugService.saveMug(this.mug).subscribe((mug) => {
if (previous === undefined || previous === false) {
this.messageService.showMessage(
this.constants.MUG,
[this.constants.MUG_OK]
);
} else {
this.messageService.showMessage(
this.constants.MUG,
[this.constants.NO_MUG]
);
}
this.mug= new Mug(mug.dates);
});
this.subscriptions.add(sub);
}
}

这是我的specs代码

describe("MugComponent", () => {
let component;
const constants: Constants = new Constants();
let messageService= jasmine.createSpyObj("messageService", ["showMessage"]);
let route;
let router: Router;
beforeEach(() => {
component = new MugComponent(
constants,
messageService,
route,
router
);
component.mug= new Mug();
});
it("should call to showMessage", () => {
spyOn(component, "showMessage");
component.saveMug(true);
expect(component.showMessage).toHaveBeenCalled();
});
});

这是错误

错误:预期的spy showMessage已被调用。在

谢谢。

什么是mugService?如果不把它注射到constructor中,你怎么能得到它?

话虽这么说,我认为你可能需要使用fakeAsync/tick使订阅发生在你的断言之前。

在组件中,我将假设现在有一个MugService

constructor(
public constants: Constants,
private messageService: MessageService,
private mugService: MugService,
public route: ActivatedRoute,
public router: Router,
) {
super(constants, route);
}
let component;
const constants: Constants = new Constants();
let messageService= jasmine.createSpyObj("messageService", ["showMessage"]);
// !! create a spy
let mugService = jasmine.createSpyObj<MugService>("MugService", ['saveMug']);
let route;
let router: Router;
beforeEach(() => {
component = new MugComponent(
constants,
messageService,
// !! give spy object to component
mugService,
route,
router
);
component.mug= new Mug();
});

// !! wrap in fakeAsync
it("should call to showMessage", fakeAsync(() => {
// !! I don't think component.showMessage exists, messageService.showMessge does and it is already spied on
// !! make mugService.saveMug and return an observable
mugService.saveMug.and.returnValue(of({})); // you can mock what it returns however you wish
component.saveMug(true);
// !! wait for the subscription to complete
tick();
expect(messageService.showMessage).toHaveBeenCalled();
});
}));

那么,我建议让模拟的messageService的saveMenu方法返回一个类似of(new Mug())的值。

我假设,测试用例应该验证,在组件的saveMug方法被执行后,messageService是否被正确调用。这可以通过执行类似的操作来完成:

describe("MugComponent", () => {
let component: MugComponent;
const constants: Constants = new Constants();
let route;
let router: Router;
let messageService= jasmine.createSpyObj("messageService", ["showMessage", "saveMenu"]);
messageService.saveMenu.and.returnValue(of(new Mug()));
beforeEach(() => {
component = new MugComponent(
constants,
messageService,
route,
router
);
component.mug = new Mug();
});
it("should call to showMessage", () => {
component.saveMug(true);
expect(messageService.showMessage).toHaveBeenCalled();
});
});

最新更新