ts-mockito icon indicating copy to clipboard operation
ts-mockito copied to clipboard

Error mocking mongoose schema with ts-mockito: “find() is not a function”

Open jsoneaday opened this issue 7 years ago • 3 comments

I am running typescript with ts-node. I am trying to run a test with mocha and chai. I also tried my test with jest. Basically most of the test runs fine. But when I attempt to mock my mongoose schema model object, I get the error mockThread.find is not a function. Odd thing is when I hover over or dot on the mock object I can see all the mongoose query methods including find. This failure occurs only when the test runs. If I remove the mock and just run my test it succeeds.

import { mock, when, instance } from "ts-mockito"; import { expect } from "chai"; import request from "supertest"; import app from "../../src/app"; import { isJSONString } from "../testHelper"; import { ThreadSchema } from "../../src/repo/models/thread"; import mongoose, { Model, DocumentQuery, Document } from "mongoose";

const Thread = mongoose.model("Thread", ThreadSchema);

describe("Test whether result is array and json stringifyable.", () => { it("Should return the error", done => { let mockThread: Model<Document, {}> = mock<Model<Document, {}>>(Thread); // I've tried adding and removing the typing info above but that did nothing when(mockThread.find()).thenReturn( new DocumentQuery<Document[], Document, {}>() );

request(app) .get("/threads") .expect(200) .end(function(err, res) { expect(isJSONString(res.body)).to.equal(true); expect(Array.isArray(res.body)).to.equal(true); done(); }); }); });

I run the test with this command mocha --require ts-node/register test/**/*.ts

jsoneaday avatar Jan 29 '19 12:01 jsoneaday

I face the same error with generic objects (no mongoose involved):

I have an RPClient that I retrieve an object Outgoing from (client.getOutgoingHandler(timeout?: number)). In Outgoing, I have a method outgoing.getServerHandles() that returns a promise and that I want to fake and return a predefined answer. The call that I want to mock is in the class under test:

client.getOutgoingHandler().getServerHandles()

To mock things I do the following:

client = mockito.mock(RSPClient);
outgoingMock = mockito.mock(Outgoing);
mockito.when(outgoingMock.getServerHandles(mockito.anyNumber())).thenResolve([serverHandle]);
mockito.when(client.getOutgoingHandler()).thenReturn(outgoingMock);

The test then runs into the following error (looks identical to yours, @dharric):

TypeError: client.getOutgoingHandler(...).getServerHandles is not a function

adietish avatar Mar 26 '19 09:03 adietish

First make sure that you are using an instance of the mock not the mock itself, You need to create an instance of the mock not the mock itself mockito.when(client.getOutgoingHandler()).thenReturn(instance(outgoingMock));

dice14u avatar Mar 27 '19 16:03 dice14u

@dice14u thx for the quick response. Did not try that yet, I'll get back to ts-mockito when writing the next tests and try to substitute sinon. If that was my error, it would maybe be a great idea to include this hint in the error?

adietish avatar Mar 28 '19 13:03 adietish