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.