filip
filip

Reputation: 1503

Stub function returning promise

I'm trying to unit test the following controller:

export class MyController extends BaseController {

  constructor() {
      super();
      this.repository = new MyRepository();
  }

  public getData(req: Request, res: Response, next: NextFunction) {

      this.repository.getData(req.params.param1).then((result) => {
          return this.ok(req, res, result.resources)        // calls ok() method from base controller
      }, (err: Error) => {
          next(err)
      });
  }
}

I would like to stub the MyRepository.getData which returns a Promise<MyResult> I also want to stub the BaseController.ok method to ensure it's called with the data returned from repo. Here is my test:

it("should call the repository", (done) => {

        var mockReq = httpMocks.createRequest();
        var mockResp = httpMocks.createResponse();
        const mockNext: NextFunction = stub();

        mockReq.params.param1 = "value1";

        let sampleResult = new MyResult();
        const getDataStub = stub(MyRepository.prototype, "getData").resolves(sampleResult);
        const okStub = stub(MyController.prototype, "ok"); 

        new MyController().getData(mockReq, mockResp, mockNext);
        expect(getDataStub).to.have.been.calledWith("value1");    // passes ok
        expect(okStub).to.have.been.called;                       // fails 
        done()
    });

The test fails when checking, if the okStub has been called at least once. If I debug the code I can see that the BaseController.ok is actually called, but after the evaluation in test.

Upvotes: 1

Views: 72

Answers (1)

Artem Dudkin
Artem Dudkin

Reputation: 588

Looks like code inside of getData.then gone to another cycle at event loop.

Try to place done() inside of this.ok like this

stub(MyController.prototype, "ok").callsFake(() => { done(); });

Upvotes: 1

Related Questions