Reputation: 798
I'm trying to do integration tests for the React-Redux application using Jest and Enzyme. The app itself works correctly and the Redux store is updated correctly after component dispatching an action. But when I run an integration test, the store has an initial value after the action being dispatched.
Here's my test file:
import SendMessageSendsay from '../utils/sendMessage'
import {testStore} from '../utils'
import {sendMessage } from '../redux/actions/messageActions'
jest.mock('../utils/sendMessage');
describe('sendMessage action', ()=> {
const message = {
subject: 'Message subject',
toEmail: '[email protected]'
}
test('Send message: Should update store correctly', () => {
const store = testStore();
const referenceState = {
messages: {
messages: [
{
date: '2019-08-30T11:36:14.813Z',
subject: 'Message subject',
trackId: '95'
}
],
isSent: true,
prevToEmail: '[email protected]'
}
}
SendMessageSendsay.mockResolvedValue({'track.id' : '95' })
store.dispatch(sendMessage(message))
const newState = store.getState();
console.log(newState);
expect(newState).toBe(referenceState);
})
});
And I get these results:
● sendMessage action › Send message: Should update store correctly
expect(received).toBe(expected) // Object.is equality
- Expected
+ Received
Object {
"messages": Object {
- "isSent": true,
- "messages": Array [
- Object {
- "date": "2019-08-30T11:36:14.813Z",
- "subject": "Message subject",
- "trackId": "95",
- },
- ],
- "prevToEmail": "[email protected]",
+ "isSent": false,
+ "messages": Array [],
+ "prevToEmail": "",
},
}
where received is the initial state in my reducer. Here's my action:
export const sendMessage = (message) => (dispatch) => {
sendMessageSendsay(message)
.then((res) => dispatch(
{
type: SEND_MESSAGE,
message: {
date: new Date(),
subject: message.subject,
trackId: res['track.id']
},
prevToEmail: message.toEmail
}
))
}
And here's the reducer:
export const initialState = {
messages : [],
isSent: false,
prevToEmail: ''
}
export default (state = initialState, action) => {
switch (action.type) {
case SEND_MESSAGE:
{
return {
...state,
messages: [
...state.messages,
action.message
],
isSent: true,
prevToEmail: action.prevToEmail
};
}
Upvotes: 1
Views: 1319
Reputation: 798
Based on @HMR comment I modified the action to this:
export const sendMessage = (message) => (dispatch) => {
return new Promise((resolve) => {
sendMessageSendsay(message)
.then((res) => resolve(dispatch(
{
type: SEND_MESSAGE,
message: {
date: new Date(),
subject: message.subject,
trackId: res['track.id']
},
prevToEmail: message.toEmail
}
)))
})
}
And test file to this:
import SendMessageSendsay from '../utils/sendMessage'
import {testStore} from '../utils'
import {sendMessage } from '../redux/actions/messageActions'
jest.mock('../utils/sendMessage');
describe('sendMessage action', ()=> {
const message = {
subject: 'Message subject',
toEmail: '[email protected]'
}
test('Send message: Should update store correctly', () => {
const store = testStore();
const referenceState = {
messages: {
messages: [
{
subject: 'Message subject',
trackId: '95'
}
],
isSent: true,
prevToEmail: '[email protected]'
}
}
SendMessageSendsay.mockResolvedValue({'track.id' : '95' })
return store.dispatch(sendMessage(message))
.then(() => {
const newState = store.getState();
expect(newState).toMatchObject(referenceState);
})
})
});
I used toMatchObject()
istead of toEqual()
to work around timestamp.
Upvotes: 1