0

I have an express app (REST API) which connects to a mongoDB cluster on MongoDB Atlas (the cloud database) during tests. I'm using Mocha to test.

I have an end-to-end test (which uses the database) but for the majority of the tests I want to mock/stub the calls to the database so that it's isolated.

I've tried using nock to intercept the network connections and mock the response, but from what I can see nock is only for http calls and mongoDB Atlas uses DNS (starts with mongodb+srv:, see here for more info) and I think this is why I can't get this to work.

I've also trying to stub the Model. I'm struggling to get this working but it seems like it might be an option?

// The route 
router.post('/test', async (req, res) => {
  const { name } = req.body;

  const example = new ExampleModel({ name: name})

  // this should be mocked
  await example.save();

  res.status(200);
});

// The test
describe('POST /example', () => {
  it('Creates an example', async () => {
    // using supertest to make http call to my API app 
    const response = await request(app)
      .post('/test')
      .type("json")
      .send({ 'name': 'test-name' })

    // expect the model to have been created and then saved to the database
  });
});

I'm expecting that when I run the test, it will make a POST to the API, which won't make a call to the database but will return fake data (as though it had).

1 Answers1

0

I've found some really useful resources and sharing them:

  • Isolating mongoose unit tests (including model methods like findOne guide
  • Stubbing the save method on a model: Stubbing the mongoose save method on a model (I just used `sinon.stub(ExampleModel.prototype, 'save').

    // example code it('Returns 400 status code', async () => { sinon.stub(ExampleModel, 'findOne').returns({ name: 'testName' }); const saveStub = sinon.stub(ExampleModel.prototype, 'save');

      const example = new ExampleModel({ name: 'testName' })
    
      const response = await request(app)
        .post('/api/test')
        .type("json")
        .send({ name: 'testName' })
    
    sinon.assert.calledWith(Hairdresser.findOne, {
          name: 'testName'
      });
    
      sinon.assert.notCalled(saveStub)
    
      assert.equal(response.res.statusCode, 400);
    });