I have an in-memory Mongoose database spinning up when we start our automated tests. I know the database spin-up code is working because if I have it run with npm start when I start my API, I can connect to it and all is well.
The problem is when it tries to do it during the tests. My server.ts has some code like this:
async function connectToDatabase() {
if (process.env.IN_MEMORY_DATABASE === 'true') {
await createInMemoryDatabase()
} else {
mongoose.connect(config.database, {
useFindAndModify: false,
useUnifiedTopology: true,
});
app.set("db", config.database);
}}
The createInMemoryDatabase looks like this:
import createDatabaseCollections from "./createDatabaseCollections";
import mongoose from "mongoose";
import { Guid } from "core/dist/utils/Guid";
import { MongoMemoryServer } from 'mongodb-memory-server';
import { resolve } from "path";
export async function createInMemoryDatabase() {
let mongod;
let databseUri;
// The next three lines are for future-proofing
// planned deprecation of old functions.
mongoose.set("useNewUrlParser", true);
mongoose.set("useUnifiedTopology", true);
mongoose.set("useCreateIndex", true);
mongoose.set("useFindAndModify", false);
mongoose.Promise = global.Promise;
// This takes a number of difference parameters to make sure the database matches
// the settings that we want so every connects nicely.
mongod = new MongoMemoryServer({
instance: {
dbName: "test-db-" + Guid.newGuid(),
},
binary: {
version: "3.6.2"
}
});
// Once the in-memory database connection is established
// it will run the function to generate the database collections.
await mongod.getUri().then(async (dbUri) => {
databseUri = dbUri;
console.log("In-Memory Database started at " + dbUri)
mongoose.connect(dbUri, {
useFindAndModify: false,
useUnifiedTopology: true,
})
mongoose.connection.on('error', (e) => {
if (e.message.code === 'ETIMEDOUT') {
console.log("Failed to start In-Memory Database: " + e);
}
})
mongoose.connection.once('open', () => {
createDatabaseCollections(mongoose.connection)
})
});
resolve(databseUri);
}
This all seems to work fine as the database is created and my code to scaffold the database does what it is suppose to.
In our test file we have a before() startement that looks like this:
let requester: ChaiHttp.Agent;
before(() => {
return new Promise(async (complete) => {
requester = chai.request(app).keepOpen();
program1 = await generateValidProgramObject(true);
user1 = await generateValidUserObject(true, Roles.User, false, program1._id);
user2 = await generateValidUserObject(true, Roles.User, false, program1._id);
setTimeout(() => {
complete()
}, 10000);
})
})
I know the timeout is gross but we have it there temporarily while we try to sort out this problem running the tests. The first two tests try to post a valid and invalid user. The first one is this:
it("Post a valid user", (done) => {
user1.Roles[0].Program = programID;
requester
.post(`/api/user/`)
.send(user1)
.end((err, res) => {
// Retrieve and save the newly posted user's ID
const results = res.text;
const start = results.indexOf("_id")
const idSegment = results.substring(start + 6, results.length);
const returnedId = idSegment.substring(0, idSegment.indexOf("\""));
id = returnedId;
expect(res).to.have.status(200);
done();
})
})
This is where we get the problem with the error about UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I've tried to find the cause of that error and I've found a lot of solutions for things when the problem exists in the actual API call, but it doesn't happen when the API is running normally and works great. So I am trying to see how we have our tests configured improperly.
Any help would be appreciated.
Aucun commentaire:
Enregistrer un commentaire