Jack
Jack

Reputation: 67

How to test asynchonous functions using sinon?

I have a class called PostController, and I trying to test the following function create:

class PostController {
  constructor(Post) {
    this.Post = Post;
  }

  async create(req, res) {
    try {
      this.validFieldRequireds(req);
      const post = new this.Post(req.body);
      post.user = req.user;
      ...some validations here
      await post.save();
      return res.status(201).send(message.success.default);
    } catch (err) {
      console.error(err.message);
      const msg = err.name === 'AppError' ? err.message : 
      message.error.default;
      return res.status(422).send(msg);
    }
 }

My test class is:

import sinon from 'sinon';
import PostController from '../../../src/controllers/posts';
import Post from '../../../src/models/post';

describe('Controller: Post', async () => {
  it.only('should call send with sucess message', () => {
    const request = {
      user: '56cb91bdc3464f14678934ca',
      body: {
        type: 'Venda',
        tradeFiatMinValue: '1',
        ... some more attributes here
      },
    };
    const response = {
      send: sinon.spy(),
      status: sinon.stub(),
    };

    response.status.withArgs(201).returns(response);
    sinon.stub(Post.prototype, 'save');
    const postController = new PostController(Post);

    return postController.create(request, response).then(() => {
      sinon.assert.calledWith(response.send);
    });
  });
});

But I'm getting the following error:

Error: Timeout of 5000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (D:\projeto\mestrado\localbonnum-back-end\test\unit\controllers\post_spec.js)

Why?

Upvotes: 0

Views: 46

Answers (1)

Zbigniew Zagórski
Zbigniew Zagórski

Reputation: 1991

Most probably it's because misuse of sinon.stub.

You've

sinon.stub(Post.prototype, 'save');

without telling what this stub will do, so in principle this stub will do nothing (meaning it returns undefined). IDK, why you don't see other like attempt to await on stub. Nevertheless, you should properly configuture 'save' stub - for example like this:

const saveStub = sinon.stub(Post.prototype, 'save');
saveStub.resolves({foo: "bar"});

Upvotes: 1

Related Questions