Unit testing Jest-如何重新构造代码以使其可测试?

Unit testing Jest-如何重新构造代码以使其可测试?,unit-testing,jestjs,puppeteer,Unit Testing,Jestjs,Puppeteer,我有下面的函数,我想为其添加两个单元测试,以涵盖选择器是否在页面上的情况 异步函数getPrice(页面,url){ 常量价格选择器=#price'; 如果(等待第页。$(价格选择器)){ 返回页.$eval(priceSelector,elem=>elem.innerText); } 返回null; } 页面在另一个函数中定义: const browser=wait puppeter.launch(); const page=wait browser.newPage(); 等待页面。转到(u

我有下面的函数,我想为其添加两个单元测试,以涵盖选择器是否在页面上的情况

异步函数getPrice(页面,url){ 常量价格选择器=#price'; 如果(等待第页。$(价格选择器)){ 返回页.$eval(priceSelector,elem=>elem.innerText); } 返回null; }
页面
在另一个函数中定义:

const browser=wait puppeter.launch();
const page=wait browser.newPage();
等待页面。转到(url);

我试图模拟
页面
,使
页面。$(价格选择器)
返回truthy或falsy,但没有成功。doc-to-mock模块中的示例很有意义,但实际上,我的代码是可测试的吗?如果没有,它应该如何构造?

只有一个地方需要重构,最好将回调函数
elem=>elem.innerText
提取到一个新函数中

例如

index.ts

导出异步函数getPrice(页面,url){
常量价格选择器=#price';
如果(等待第页。$(价格选择器)){
返回页.$eval(priceSelector,elem=>elem.innerText);
}
返回null;
}
索引规范ts

从“/”导入{getPrice};
常数页={
$:jest.fn(),
$eval:jest.fn()
};
在每个之前(()=>{
jest.resetAllMocks();
});
测试('should eval',async()=>{
page.$.mockResolvedValueOnce(true);
第页$eval.mockReturnValueOnce(“虚拟数据”);
const actualValue=wait getPrice(第页,'example.com');
expect(实际值).toBe(“虚拟数据”);
期望(第.$)页。使用(#价格)调用;
expect(page.$eval).toBeCalledWith(“#price”,expect.any(Function));
});
test('应返回null',async()=>{
page.$.mockResolvedValueOnce(false);
const actualValue=wait getPrice(第页,'example.com');
expect(实际值).toBeNull();
期望(第.$)页。使用(#价格)调用;
expect(page.$eval).not.toBeCalled();
});
您可以像这样测试它,但是不会测试和覆盖回调函数

单元测试结果和覆盖率报告:

PASS src/stackoverflow/58651192/index.spec.ts
✓ 应评估(6ms)
✓ 应返回null(2ms)
----------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
----------|----------|----------|----------|----------|-------------------|
所有文件| 85.71 | 100 | 50 | 100 ||
指数.ts | 85.71 | 100 | 50 | 100 ||
----------|----------|----------|----------|----------|-------------------|
测试套件:1个通过,共1个
测试:2次通过,共2次
快照:共0个
时间:4.786秒,估计7秒
如果我们像这样提取
$eval
的回调函数:

export const evalCallback=elem=>elem.innerText;
我们可以很容易地测试它:

test('evalCallback',()=>{
const actualValue=evalCallback({innerText:'unittest'});
expect(实际值).toBe(“单元测试”);
});
100%覆盖率的单元测试结果:

PASS src/stackoverflow/58651192/index.spec.ts(9.066s)
✓ 应评估(10ms)
✓ 应返回null(1ms)
✓ evalCallback(1ms)
----------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
----------|----------|----------|----------|----------|-------------------|
所有文件| 100 | 100 | 100 | 100 ||
index.ts | 100 | 100 | 100 | 100 ||
----------|----------|----------|----------|----------|-------------------|
测试套件:1个通过,共1个
测试:3次通过,共3次
快照:共0个
时间:10.804s