Matarishvan
Matarishvan

Reputation: 2422

Writing JEST unit test for a simple function

Basically this is my react code

    getDetails: function () {
        var apiUrl = ConfigStore.get('api')
        request
            .get(apiUrl)
            .set('X-Auth-Token', AuthStore.jwt)
            .set('Accept', 'application/json')
            .end(function (err, response) {
                if (!err) {
                    if(response.text.indexOf("string") > -1){
                        this.dispatch('COMMAND1', response);
                    }
                    else {
                        this.dispatch('COMMAND2', response.body.options);
                    }
                }
                else {
                    this.dispatch('COMMAND3', response && response.body);
                }
            }.bind(this));
    }

I've written an unit test for the above function of COMMAND1

    it('Getting Latest Details', () => {
    let eventSpy = sinon.spy();
        require('superagent').__setMockResponse({
            body: {               
                firstName: 'blah',
                lastName: 'm ',
                username: 'blah',
                text: {
                    text : jest.fn()
                }               
            }
        }); 
        let dispatchListener = AppDispatcher.register((payload) => {
            if (payload.action.type === 'COMMAND1') {
                eventSpy(payload.action.payload);               
            }
        });     

        AuthStore.loggedIn = jest.genMockFunction().mockReturnValue(true);
        AuthStore.getToken = jest.genMockFunction().mockReturnValue('545r5e45er4e5r.erereere');
        MedsAlertsActions.getDetails();
        expect(eventSpy.called).toBe(true);
        dispatch('COMMAND1', data);
        AppDispatcher.unregister(dispatchListener);
});   

When i run

npm test myfile.test

I'm getting

TypeError: Cannot read property 'indexOf' of undefined
  1. So how do i put the indexOf the response in my body? How to resolve the type error
  2. How to write test cases for command2 and command3 as well.

Upvotes: 0

Views: 459

Answers (1)

Andres Mateo Otalvaro
Andres Mateo Otalvaro

Reputation: 141

I can see you're using sinon. You can create a sandbox and a fake server in it who return the response expected for each test case. Something like this, for example:

describe('your test suite', () => {
  let sandbox;
  let server;

  beforeAll(() => {
    sandbox = sinon.sandbox.create();
    server = sandbox.useFakeServer();
  });

  it('Calls COMMAND1', () => {

    //Sinon takes some ms to respond, so you have to use a setTimeout
    setTimeout(
      () => server.respond([200, { 'Content-Type': 'text/html' }, 'some string']),
      0
      );

    // Put here your assertions
  });


});

You can use server.restore() and sandbox.restore() to clean each one when you needed. Besides, you can access the requests made with sandbox.requests

Here's a great post that may help you: https://medium.com/@srph/axios-easily-test-requests-f04caf49e057, it's about axios, but you can implement it in the same way.

Also, you can know more about it at the official sinon documentation for sandboxes: http://sinonjs.org/releases/v1.17.7/sandbox

Upvotes: 1

Related Questions