[Mongoose][timekeeper] TypeError: Undefined type `FakeDate` at `fieldName`
I’ll introduce how I got stuck with FakeDate while using timekeeper, a time manipulation module, in test code for a web service with Node.js + Mongoose configuration.
Test code that causes errors with timekeeper.freeze and new mongoose.Schema
'use strict';
const mongoose = require("mongoose");
const timekeeper = require("timekeeper");
describe("FakeDate error", () => {
timekeeper.freeze(new Date());
let schema = new mongoose.Schema({
createdAt: {
type: Date
}
});
timekeeper.reset();
});
Error message TypeError: Undefined type FakeDate
$ mocha test.js
/Users/username/works/myapp/node_modules/mongoose/lib/schema.js:483
throw new TypeError('Undefined type `' + name + '` at `' + path +
^
TypeError: Undefined type `FakeDate` at `createdAt`
Did you try nesting Schemas? You can only nest using refs or arrays.
at Function.Schema.interpretAsType (/Users/username/works/myapp/node_modules/mongoose/lib/schema.js:483:11)
at Schema.path (/Users/username/works/myapp/node_modules/mongoose/lib/schema.js:415:29)
at Schema.add (/Users/username/works/myapp/node_modules/mongoose/lib/schema.js:310:12)
at new Schema (/Users/username/works/myapp/node_modules/mongoose/lib/schema.js:88:10)
at Suite. (/Users/username/works/myapp/test.js:8:16)
at context.describe.context.context (/Users/username/works/myapp/node_modules/mocha/lib/interfaces/bdd.js:73:10)
at Object. (/Users/username/works/myapp/test.js:6:1)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (/Users/username/works/myapp/node_modules/coffee-script/lib/coffee-script/coffee-script.js:211:36)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at /Users/username/works/myapp/node_modules/mocha/lib/mocha.js:157:27
at Array.forEach (native)
at Mocha.loadFiles (/Users/username/works/myapp/node_modules/mocha/lib/mocha.js:154:14)
at Mocha.run (/Users/username/works/myapp/node_modules/mocha/lib/mocha.js:326:31)
at Object. (/Users/username/works/myapp/node_modules/mocha/bin/_mocha:350:7)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:974:3
timekeeper processes swapping JavaScript’s Date object with timekeeper’s custom-defined FakeDate object as follows:
/** * Replace the `Date` with `FakeDate`. */ function useFakeDate() { Date = FakeDate }/**
- Restore the
Date
toNativeDate
. */ function useNativeDate() { Date = NativeDate }
When Date is swapped with FakeDate instead of Date, calling new mongoose.Schema throws an exception because FakeDate is not a SchemaType defined in MongooseTypes. Roughly speaking.
The Mongoose code that checks SchemaType in new mongoose.Schema is around here: lib/schema.js#L652-L671
I don’t think there are many cases where you explicitly write new mongoose.Schema in test code between timekeeper.freeze and timekeeper.reset. So, modules that define Models with new mongoose.Schema processing should be require()d beforehand to avoid errors.
That’s all from the Gemba.