如何在 Jasmine/Angular 中测试 BeforeInstallPromptEvent?
How can I test the BeforeInstallPromptEvent in Jasmine/Angular?
我正在为对话框组件编写测试,它处理调用函数时手动提示的 PWA 安装事件。然后它将解决从 BeforeInstallPromptEvent.userChoice
属性.
返回的承诺
然而,当我尝试测试这个函数时,我从 jasmine 收到错误消息:
'userChoice.then is not a function'
这是我理解的,因为我尝试用 spyOn 监视它然后检查结果。
我用 Promises 尝试了一些其他的东西,因为 userChoice returns 一个已解决的 promise (https://developer.mozilla.org/en-US/docs/Web/API/BeforeInstallPromptEvent) 但到目前为止没有任何效果。
这是我要测试的功能。 BeforeInstallPromptEvent
存储在从 app.ts
传递到组件的 installEvent 对象中,然后存储在数据中。
this.data.installEvent.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
doSomething();
在我的测试规范中,我使用以下内容创建了一个模拟数据对象:
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve().then(() => {
return { choiceResult: { outcome: "accepted" } };
}),
},
};
到目前为止我的测试规范(经过多次不同的尝试)是这样的:
it("should do something after user accepted", fakeAsync(() => {
mockData.installEvent.userChoice.then((result) => {
return result.choiceResult.outcome;
//this test returns true
expect(result.choiceResult.outcome).toEqual("accepted");
});
flush();
//but the function gets never called
expect(component.doSomething).toHaveBeenCalled();
});
或者在 userChoice
上使用 spyOn
函数产生错误:
it("should do something after user accepted", () => {
spyOn(mockData.installEvent, "userChoice").and.returnValue("accepted");
expect(mockData.installEvent.userChoice).toBe("accepted)
expect(component.doSomething).toHaveBeenCalled();
});
有了这个,我已经成功地测试了 data.installEvent.prompt
函数正在被调用。
但我不知道如何测试 userChoice
Promise 解析为“已接受”,然后触发 if 条件。
请帮帮我。由于我是测试方面的初学者(在 Angular 中),因此最好能解释一下测试此类 Promises 背后的方法。
非常感谢您!
问题是您正在解决已经在 mockData
中的承诺,而间谍没有返回承诺。
方法一
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve({ choiceResult: { outcome: "accepted" } }),
},
};
it("should do something after user accepted", fakeAsync(() => {
mockData.installEvent.userChoice.then((result) => {
// return result.choiceResult.outcome;, remove return here and only test the assertion
//this test returns true
expect(result.choiceResult.outcome).toEqual("accepted");
expect(component.doSomething).toHaveBeenCalled(); // make sure doSomething gets called
});
flush(); // flush the promises
});
方法二(做不到)
it("should do something after user accepted", () => {
// you can't spy on userChoice since you can only spy on methods/functions and not variables
spyOn(mockData.installEvent, "userChoice").and.returnValue("accepted");
expect(mockData.installEvent.userChoice).toBe("accepted)
expect(component.doSomething).toHaveBeenCalled();
});
方法 2 无法完成,因为您只能 spyOn
方法和函数,而不能使用属性。
非常感谢@AliF50 的回答!
我尝试了方法 1,除了我后来发现的一个小错误外,它起作用了:
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve({ choiceResult: { outcome: "accepted" } }),
},
};
需要
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve( { outcome: "accepted" } ),
},
};
因为 beforeinstallprompt.userChoice
属性 的结构给出了一个具有关键结果的对象,如 if:
if (choiceResult.outcome === "accepted")
所以在我们的例子中解决测试规范中的承诺时的结果等于 if 条件中的 choiceResult。
更改后一切正常!
我正在为对话框组件编写测试,它处理调用函数时手动提示的 PWA 安装事件。然后它将解决从 BeforeInstallPromptEvent.userChoice
属性.
然而,当我尝试测试这个函数时,我从 jasmine 收到错误消息:
'userChoice.then is not a function'
这是我理解的,因为我尝试用 spyOn 监视它然后检查结果。
我用 Promises 尝试了一些其他的东西,因为 userChoice returns 一个已解决的 promise (https://developer.mozilla.org/en-US/docs/Web/API/BeforeInstallPromptEvent) 但到目前为止没有任何效果。
这是我要测试的功能。 BeforeInstallPromptEvent
存储在从 app.ts
传递到组件的 installEvent 对象中,然后存储在数据中。
this.data.installEvent.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
doSomething();
在我的测试规范中,我使用以下内容创建了一个模拟数据对象:
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve().then(() => {
return { choiceResult: { outcome: "accepted" } };
}),
},
};
到目前为止我的测试规范(经过多次不同的尝试)是这样的:
it("should do something after user accepted", fakeAsync(() => {
mockData.installEvent.userChoice.then((result) => {
return result.choiceResult.outcome;
//this test returns true
expect(result.choiceResult.outcome).toEqual("accepted");
});
flush();
//but the function gets never called
expect(component.doSomething).toHaveBeenCalled();
});
或者在 userChoice
上使用 spyOn
函数产生错误:
it("should do something after user accepted", () => {
spyOn(mockData.installEvent, "userChoice").and.returnValue("accepted");
expect(mockData.installEvent.userChoice).toBe("accepted)
expect(component.doSomething).toHaveBeenCalled();
});
有了这个,我已经成功地测试了 data.installEvent.prompt
函数正在被调用。
但我不知道如何测试 userChoice
Promise 解析为“已接受”,然后触发 if 条件。
请帮帮我。由于我是测试方面的初学者(在 Angular 中),因此最好能解释一下测试此类 Promises 背后的方法。
非常感谢您!
问题是您正在解决已经在 mockData
中的承诺,而间谍没有返回承诺。
方法一
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve({ choiceResult: { outcome: "accepted" } }),
},
};
it("should do something after user accepted", fakeAsync(() => {
mockData.installEvent.userChoice.then((result) => {
// return result.choiceResult.outcome;, remove return here and only test the assertion
//this test returns true
expect(result.choiceResult.outcome).toEqual("accepted");
expect(component.doSomething).toHaveBeenCalled(); // make sure doSomething gets called
});
flush(); // flush the promises
});
方法二(做不到)
it("should do something after user accepted", () => {
// you can't spy on userChoice since you can only spy on methods/functions and not variables
spyOn(mockData.installEvent, "userChoice").and.returnValue("accepted");
expect(mockData.installEvent.userChoice).toBe("accepted)
expect(component.doSomething).toHaveBeenCalled();
});
方法 2 无法完成,因为您只能 spyOn
方法和函数,而不能使用属性。
非常感谢@AliF50 的回答! 我尝试了方法 1,除了我后来发现的一个小错误外,它起作用了:
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve({ choiceResult: { outcome: "accepted" } }),
},
};
需要
const mockData = {
installEvent: {
prompt: () => {},
userChoice: Promise.resolve( { outcome: "accepted" } ),
},
};
因为 beforeinstallprompt.userChoice
属性 的结构给出了一个具有关键结果的对象,如 if:
if (choiceResult.outcome === "accepted")
所以在我们的例子中解决测试规范中的承诺时的结果等于 if 条件中的 choiceResult。
更改后一切正常!