MockSSE
This project is a port/rewrite of MockEvent (which targets the browser). Instead, this project was designed for mocking EventSource (specifically the npm package eventsource) /Server Sent Events (SSE) where both your server side and client side are written for the NodeJS platform.
MockSSE simulates SSE.
Useful if you want to:
- Build the client side without having the server side available to you
- Or simply unit testing -> C/I, rather than integration tests
This project has no dependencies other than native modules.
Install
npm install mocksse --save-dev
Usage
All examples include:
- How to instantiate a
MockEvent
which streams the data - How to instantiate an
EventSource
which consumes the data - Adding at least one event listener
As well as the following examples:
- The tests demonstrate how to use the project along with the feature set
- The project that uses
mocksse
for testing the client side of its server sent events (SSE) can be seen at the purpleteam repository
Example 0
Getting started with the least amount of work (based on test should handle an event to relative url
).
const { MockEvent, EventSource } = require('mocksse');
new MockEvent({
url: '/your-relative-or-absolute-url',
responses: [
{ type: 'a message event', data: 'a short message' }
]
});
const evtSource = new EventSource('/your-relative-or-absolute-url');
evtSource.addEventListener('a message event', (event) => {
});
Example 1
Multiple event listeners (based on test should handle an event with setInterval, and collection of full responses).
const { MockEvent, EventSource } = require('mocksse');
new MockEvent({
url: 'http://noPlaceLikeHome:2000/your-route',
setInterval: 10,
responses: [
{ lastEventId: 'event Id One', type: 'progressEvent', data: { progress: 'Look mum, I am making great progress' } },
{ lastEventId: 'event Id Two', type: 'pctCompleteEvent', data: { pctComplete: 11 } },
{ lastEventId: 'event Id three', type: 'temperatureEvent', data: { temperature: 25 } }
]
});
const evtSource = new EventSource('http://noPlaceLikeHome:2000/your-route');
evtSource.onopen = (event) => {
};
evtSource.addEventListener('progressEvent', (event) => {
});
evtSource.addEventListener('pctCompleteEvent', (event) => {
});
evtSource.addEventListener('temperatureEvent', (event) => {
});
url
: The relative or full URL for your Server Sent Event API. This is the URL we will subscribe to via EventSource
setInterval
: Miliseconds to wait before sending the next event/responseresponses
: A list of event/responses to send and the order in which to send them
lastEventId
can be set and readtype
: Server Sent Events can have a name that you directly subscribe to in case you want to handle that name differently. In the above example we require you to subscribe to 3 different names progressEvent
, pctCompleteEvent
, and temperatureEvent
. A working example of this can be seen in the purpleteam projectdata
: The data you want to send
Example 2
Dynamically make responses and then have them stream
ed (based on test response function should be called, which then sends event).
const { MockEvent, EventSource } = require('mocksse');
new MockEvent({
url: 'http://noPlaceLikeHome:2000/your-route',
setInterval: [100, 200],
response: (mockEvent, evtSource) => {
const data = [
{ lastEventId: 'event Id One', type: 'yourEvent', data: { yourProp: 'Wish I was done!' } },
{ lastEventId: 'event Id Two', type: 'yourEvent', data: { yourProp: 'Oh, wow, nearly done!' } }
];
mockEvent.stream(data);
}
});
const evtSource = new EventSource('http://noPlaceLikeHome:2000/your-route');
evtSource.addEventListener('yourEvent', (event) => {
});
This uses the response
attribute instead of the plural responses
method. Here you can build build a list of responses to send and then stream them when you're ready.
The stream
method respects the setInterval
property you specified. Also notice that setInterval
can be set to an int
, float
, or array
representing a min/max range of milliseconds.
Technically you can use any method and then call handler.stream
. The benefit of using the response
hook is that you get the mockEvent
and evtSource
object in case you need those values for anything. Example 3 shows how you can benefit from these objects.
Example 3
Dynamically make responses and then stream
them yourself within your response
function (based on test response function should be called, which then streams events itself).
const { MockEvent, EventSource } = require('mocksse');
new MockEvent({
url: 'http://noPlaceLikeHome:2000/your-route',
setInterval: [100, 200],
response: (mockEvent, evtSource) => {
const data = [
{ lastEventId: 'event Id One', type: 'yourEvent', data: { yourProp: 'Wish I was done!' } },
{ lastEventId: 'event Id Two', type: 'yourEvent', data: { yourProp: 'Oh, wow, nearly done!' } }
];
const intervalId = setInterval(() => {
const responseData = data.shift() || clearInterval(intervalId);
if (responseData) mockEvent.dispatchEvent(responseData);
}, mockEvent.setInterval);
}
});
const evtSource = new EventSource('http://noPlaceLikeHome:2000/your-route');
evtSource.addEventListener('yourEvent', (event) => {
});
Here we write our own stream
method that loops through data and sends. Still respecting the setInterval
attribute and leveraging the internal dispatchEvent
method of the mockEvent
. This is not recommended, it's just used as an example to show the amount of access you have to all attributes. Using the dispatchEvent
method directly overwrites the stream
attribute and will not respect other queues that maybe set by you later.
Example 4
Closing the EventSource then subscribing to an event will invoke the error handler if you have subscribed to onerror
(based on test closing the EventSource then subscribing to an event should invoke the error handler
).
const { MockEvent, EventSource } = require('mocksse');
const mockEvent = new MockEvent({
url: 'http://noPlaceLikeHome:2000/your-route',
verbose: true,
responses: [
{ type: 'a message event', data: 'a short message' }
]
});
const evtSource = new EventSource('http://noPlaceLikeHome:2000/your-route');
evtSource.close();
evtSource.addEventListener('a message event', (event) => {
});
evtSource.onerror = (error) => {
};
Contribution
Please open an issue to discus the proposed change before submitting a merge request.
Acknowledgements
This project is a port/rewrite of MockEvent, which targets the browser.
Inspiration was also taken from eventsourcemock, which is also browser focussed and very minimal.
License
Copyright Kim Carter and other contributors, Licensed under MIT.