A dependency free mock for EventSource objects.
To setup the mock create a new file where the mock is assigned to the window object.
// __test__/configJSDom.js
import EventSource from 'eventsourcemock';
Object.defineProperty(window, 'EventSource', {
value: EventSource,
});Then instruct Jest to use that file during setup in package.json.
"jest": {
"setupFiles": [
"./__test__/configJSDom.js"
]
}Suppose we want to test this component, which updates its state when a message is received from an EventSource instance.
export default class Component extends React.Component {
props: Props;
state: State;
source: $PropertyType<window, 'EventSource'>;
constructor(props: Props) {
super(props);
this.state = {
counter: 0,
};
}
componentDidMount() {
this.source = new window.EventSource('http://example.com/events');
this.source.addEventListener('foo', messageEvent => {
this.setState({ counter: parseInt(messageEvent.data, 10) });
});
}
componentWillUnmount() {
this.source.close();
}
render() {
return <div className="Component">{this.state.counter}</div>;
}
}We can write a test file that grabs the source from the global sources object and simulates messages:
// @flow
import React from 'react';
import { mount } from 'enzyme';
import Component from './Component';
import { sources } from 'eventsourcemock';
const messageEvent = new MessageEvent('foo', {
data: '1',
});
describe('update counter on SSE', () => {
let wrapper;
beforeAll(() => {
wrapper = mount(<Component />);
sources['http://example.com/events'].emitOpen();
});
it('should initialise counter to 0', () => {
expect(wrapper.state('counter')).toBe(0);
});
it('should display "0"', () => {
expect(wrapper.text()).toBe('0');
});
it('should update the counter to 1', () => {
sources['http://example.com/events'].emit(
messageEvent.type,
messageEvent
);
expect(wrapper.state('counter')).toBe(1);
});
it('should close the EventSource on unmount', () => {
wrapper.unmount();
expect(sources['http://example.com/events'].readyState).toBe(2);
});
});sources holds the EventSource instances created.
import { sources } from 'eventsourcemock';EventSource mocks window.EventSource, providing methods to simulate messages and errors from the network.
import EventSource from 'eventsourcemock';EventSource(
url: string,
options?: {
withCredentials: boolean
}
)A reference to the node EventEmitter instance used internally.
See eventSource.onopen.
See eventSource.onerror.
See eventSource.url.
See eventSource.withCredentials.
Calls each of the listeners registered for the event named eventName, providing messageEvent as argument.
Example
const messageEvent = new MessageEvent('type', {
data: 'message event data'
});
source.emit(messageEvent.type, messageEvent);Simulates the opening of a connection. It sets the ready state to open and invokes the callback.
Simulates dispatching of a message, it invokes the onmessage callback.
Simulates dispatching an error event on the EventSource instance. Causes onerror to be called.
Example (jest)
const onErrorSpy = jest.fn();
const error = new Error('Something went wrong.');
eventSource.onerror = onErrorSpy;
eventSource.emitError(error);
expect(onErrorSpy).toHaveBeenCalledWith(error);See EventTarget.addEventListener.
See EventTarget.removeEventListener
See EventSource.close.