Javascript 使用Jest和ES模块测试客户端SSE

Javascript 使用Jest和ES模块测试客户端SSE,javascript,ecmascript-6,jestjs,server-sent-events,Javascript,Ecmascript 6,Jestjs,Server Sent Events,目标是将EventSource相关功能放在一个类中,例如: export default class EventSourceSetup { constructor() { let eventSource = new EventSource('http://localhost'); eventSource.addEventListener('loading', function (event) { }) eventSou

目标是将EventSource相关功能放在一个类中,例如:

export default class EventSourceSetup {
    constructor() {
        let eventSource = new EventSource('http://localhost');

        eventSource.addEventListener('loading', function (event) {

        })

        eventSource.addEventListener('loaded', function (event) {

        })

        eventSource.addEventListener('error', function (event) {

        })

        eventSource.onerror = error => {
            console.error('EventSource failed: ', error);
        };
    }
}
应模拟服务器,并使用浏览器中带有
window
EventSource
的完整客户端功能。 并对其进行测试,例如:

import EventSourceSetup from './thumbnails'

describe('SSE', () => {
    beforeAll(() => {
    });

    it('first', () => {
        const eventSourceSetup = new EventSourceSetup();
    });
});
但当我这样做时,我看到以下错误:

ReferenceError: EventSource is not defined

    at new EventSourceSetup (/Users/pharmosan/IdeaProjects/thumbnails-frontend/thumbnails.js:3:27)
    at Object.<anonymous> (/Users/pharmosan/IdeaProjects/thumbnails-frontend/thumbnails.test.js:8:34)
    at Object.asyncJestTest (/Users/pharmosan/IdeaProjects/thumbnails-frontend/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
    at /Users/pharmosan/IdeaProjects/thumbnails-frontend/node_modules/jest-jasmine2/build/queueRunner.js:43:12
    at new Promise (<anonymous>)
    at mapper (/Users/pharmosan/IdeaProjects/thumbnails-frontend/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
    at /Users/pharmosan/IdeaProjects/thumbnails-frontend/node_modules/jest-jasmine2/build/queueRunner.js:73:41
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
ReferenceError:未定义EventSource
在新的EventSourceSetup(/Users/pharmosan/IdeaProjects/thumbnails frontend/thumbnails.js:3:27)
反对。(/Users/pharmosan/IdeaProjects/thumbnails frontend/thumbnails.test.js:8:34)
在Object.asyncJestTest(/Users/pharmosan/IdeaProjects/thumbnails frontend/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
at/Users/pharmosan/IdeaProjects/thumbnails frontend/node_modules/jest-jasmine2/build/queueRunner.js:43:12
在新的承诺()
在mapper(/Users/pharmosan/IdeaProjects/thumbnails frontend/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
at/Users/pharmosan/IdeaProjects/thumbnails frontend/node_modules/jest-jasmine2/build/queueRunner.js:73:41
在处理和拒绝时(内部/process/task_queues.js:97:5)

以下是单元测试解决方案:

index.js

导出默认类EventSourceSetup{
事件源;
构造函数(){
让eventSource=新的eventSource('http://localhost');
this.eventSource=eventSource;
eventSource.addEventListener('loading',函数(事件){
console.log(“加载”);
});
eventSource.addEventListener('loaded',函数(事件){
console.log('loaded');
});
eventSource.addEventListener('error',函数(事件){
console.log('error');
});
eventSource.onerror=(错误)=>{
错误('EventSource失败:',错误);
};
}
}
index.test.js

从“”导入EventSourceSetup;
常数mEventSourceInstance={
addEventListener:jest.fn(),
};
const mEventSource=jest.fn(()=>mEventSourceInstance);
global.EventSource=mEventSource;
描述('SSE',()=>{
之后(()=>{
开玩笑。clearAllMocks();
});
它('first',()=>{
mEventSourceInstance.addEventListener.mockImplementation((事件,处理程序)=>{
如果(事件=='loading'| |事件=='loaded'){
handler();
}
});
constlogspy=jest.spyOn(控制台,'log');
新建EventSourceSetup();
expect(mEventSource).toBeCalledWith('http://localhost');
期望(mEventSourceInstance.addEventListener).toBeCalledTimes(3);
expect(logSpy).toBeCalledWith('loading');
expect(logSpy).toBeCalledWith('loaded');
});
它('应该处理错误',()=>{
mEventSourceInstance.addEventListener.mockImplementation((事件,处理程序)=>{
如果(事件=='error'){
handler();
}
});
constlogspy=jest.spyOn(控制台,'log');
新建EventSourceSetup();
expect(mEventSource).toBeCalledWith('http://localhost');
期望(mEventSourceInstance.addEventListener).toBeCalledTimes(3);
expect(logSpy).toBeCalledWith('error');
});
它('应该处理onerror',()=>{
const eventSourceSetup=new eventSourceSetup();
const errorLogSpy=jest.spyOn(控制台,'error');
const mError=新错误(“网络”);
eventSourceSetup.eventSource.onerror(mError);
expect(errorLogSpy).toBeCalledWith('EventSource failed:',mError);
});
});
100%覆盖率的单元测试结果:

PASS stackoverflow/60409694/index.test.js(9.572s)
上海证券交易所
✓ 第一(31毫秒)
✓ 应处理错误(1ms)
✓ 应处理一个错误(19毫秒)
console.log node_modules/jest mock/build/index.js:814
加载
console.log node_modules/jest mock/build/index.js:814
加载
console.log node_modules/jest mock/build/index.js:814
错误
console.log节点_umodules/jest mock/build/index.js:814
错误
console.error节点_modules/jest mock/build/index.js:814
EventSource失败:错误:网络
反对。(/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/stackoverflow/60409694/index.test.js:44:20)
在Object.asyncJestTest(/Users/ldu020/workspace/github.com/mrdulin/react apollo graphql初学者工具包/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
解析时(/Users/ldu020/workspace/github.com/mrdulin/react apollo graphql初学者工具包/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
在新的承诺()
在mapper(/Users/ldu020/workspace/github.com/mrdulin/react apollo graphql初学者工具包/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
在promise.then(/Users/ldu020/workspace/github.com/mrdulin/react apollo graphql starter kit/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
在进程中。_tick回调(内部/process/next_tick.js:68:7)
----------|---------|----------|---------|---------|-------------------
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s
----------|---------|----------|---------|---------|-------------------
所有文件| 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
测试套件:1个通过,共1个
测试:3次通过,共3次
快照:共0个
时间:12.222s
jest.config.js

module.exports={
预设:'ts jest/presets/js with ts',
测试匹配:['**/?(*)+(规范测试)。[jt]s?(x)],
没错,
};

不知道这是否对您有帮助,但如果我是您,我会尝试将
EventSource
注入构造函数,因为这将使测试更容易(您可以简单地存根整个
EventSource
,因为这不是您正在测试的,是吗?)@SebastianKaczmarek我想模拟服务器并使用完整的客户端功能。现在很清楚,你可以使用polyfill