jefflau / jest-fetch-mock

Jest mock for fetch
MIT License
886 stars 118 forks source link

Error in action creator Testing #60

Open bhatti-waqas opened 6 years ago

bhatti-waqas commented 6 years ago

Can anyone help me out about the error I am getting while testing "self.body is not a function"

This is my code

`it('creates GET_PROPERTY_DETAILS_REQUEST when getting details', () => {

    let normalizedData = normalize(propertyDetailsMockData, propertyDetails)
    fetch.mockResponse(propertyDetailsMockData)
    const initialState = {}
    // console.log(propertyDetails)
    //fetch.mockResponse(normalizedData)
    const store = mockStore({propertyDetails:initialState})

    console.log(store.getActions())
    const expectedActions = [
        { type: GET_PROPERTY_DETAILS_REQUEST, propertyId:"1853633" },
        { type: GET_PROPERTY_DETAILS_SUCCESS,  propertyId:"1853633", body:{propertyDetailsMockData}}
    ]

    return store.dispatch(getPropertyDetails('1853633')).then(() => {
        // return of async actions
        expect(store.getActions()).toEqual(expectedActions)
    })
})`

and test case fails with the error "error": [TypeError: self.body.on is not a function],

ovation22 commented 6 years ago

Same issue here.

jefflau commented 6 years ago

Have you guys got a repo that i can look at?

bhatti-waqas commented 6 years ago

@jefflau : Here is the link to the repository I created a test project. Please check action "propertyDetails.js" and let me know if I am missing something. Any help would be much appericiated. thanks https://github.com/bhatti-waqas/react-native-redux-jest

ovation22 commented 6 years ago

I could work up something, but it's similar to above. The difference is that ours is ejected.

"jest": "20.0.4", "jest-fetch-mock": "^1.5.0", "redux-mock-store": "^1.5.1" "es6-promise": "^4.2.4", "whatwg-fetch": "^2.0.3"

jefflau commented 6 years ago

@bhatti-waqas I had a look at it briefly, but didn't have time to take a deep dive. Have you tried a simpler example?

koenoe commented 6 years ago

@jefflau I'm having the same problem when I'm testing a response body in JSON format. If I'm testing a text response it's working fine. You can have a look here: https://github.com/koenoe/beschikbarefreelancer/blob/develop/src/utils/ApiUtils.spec.js

The test that's commented out is throwing the error [TypeError: self.body.on is not a function].

rkram5424 commented 6 years ago

Since you're getting a string response and then converting it to JSON, you need to JSON.stringify the mocked data. I think what's going on here is that it's trying to JSONify something that's already JSON.

koenoe commented 6 years ago

@rkram5424 That worked! Thanks. I'll look later if I can do a PR, because this solution is not ideal though.

Shelob9 commented 6 years ago

I found this issue when I got this error. I want to share my solution. Might be worth adding this to the docs. In my case I had tests like this:

describe( 'ProLocalSettingClient', () => {
        const settings = {};//this is an actual mock of my settings.

    beforeEach(() => {
        fetch.resetMocks();
    });
    it('Gets settings', () => {
        fetch.mockResponseOnce(new Response(JSON.stringify(settings)));
        const client = new ProLocalSettingClient('https://hiroy.club/api/settings');
        client.getSettings().then(res => {
            expect(res).toEqual(settings);
        });
        expect(fetch.mock.calls).toHaveLength(1);
    });
});

I was already serializing my mock data, which @rkram5424 had shown was the issue for @koenoe . In my case I was not catching an error:

describe( 'ProLocalSettingClient', () => {
        const settings = {};//this is an actual mock of my settings.

    beforeEach(() => {
        fetch.resetMocks();
    });
    it('Gets settings', () => {
        fetch.mockResponseOnce(new Response(JSON.stringify(settings)));
        const client = new ProLocalSettingClient('https://hiroy.club/api/settings');
        client.getSettings().then(res => {
            expect(res).toEqual(settings);
        },error => {
            //nothing here, but test will generate an error without it.
        });
        expect(fetch.mock.calls).toHaveLength(1);
    });
});

I thought that since the function being tested -- client.getSettings() -- catches and handles API errors my tests wouldn't need the catch. That's the confusion that led to this error for me. I hope this helps someone else.

Another option:

client.getSettings().then(  response => {
    expect( response ).toEqual( expectedResponse );
}).catch((error) => {
    // eslint-disable-next-line no-console
    console.log(error);
});