Асинхронные проблемы с JEST и MongoDB - PullRequest
0 голосов
/ 23 октября 2018

Я получаю противоречивые результаты с JEST, когда пытаюсь удалить элементы из коллекции MongoDB с помощью хука beforeEach ().

Моя схема и модель Mongoose определены как:

// Define Mongoose wafer sort schema
const waferSchema = new mongoose.Schema({
  productType: {
    type: String,
    required: true,
    enum: ['A', 'B'],
  },
  updated: {
    type: Date,
    default: Date.now,
    index: true,
  },
  waferId: {
    type: String,
    required: true,
    trim: true,
    minlength: 7,
  },
  sublotId: {
    type: String,
    required: true,
    trim: true,
    minlength: 7,
  },
}

// Define unique key for the schema
const Wafer = mongoose.model('Wafer', waferSchema);
module.exports.Wafer = Wafer;

Мои JEST-тесты:

describe('API: /WT', () => {
  // Happy Path for Posting Object
  let wtEntry = {};

  beforeEach(async () => {
    wtEntry = {
      productType: 'A',
      waferId: 'A01A001.3',
      sublotId: 'A01A001.1',
    };
    await Wafer.deleteMany({});
    // I also tried to pass in done and then call done() after the delete
  });

  describe('GET /:id', () => {
    it('Return Wafer Sort Entry with specified ID', async () => {
      // Create a new wafer Entry and Save it to the DB
      const wafer = new Wafer(wtEntry);
      await wafer.save();

      const res = await request(apiServer).get(`/WT/${wafer.id}`);
      expect(res.status).toBe(200);
      expect(res.body).toHaveProperty('productType', 'A');
      expect(res.body).toHaveProperty('waferId', 'A01A001.3');
      expect(res.body).toHaveProperty('sublotId', 'A01A001.1');
    });
}

Поэтому ошибка, которую я всегда получаю, связана с дублированием ключей при запускемои тесты более одного раза: MongoError: E11000 коллекция ошибок дубликатов ключей: promis_tests.promiswts index: waferId_1_sublotId_1 dup key: {: "A01A001.3",: "A01A001.3"}

Но я не понимаю, какЯ могу получить эту двойную ключевую ошибку, если beforeEach () запускался правильно.Я пытаюсь очистить коллекцию неправильно?Я попытался передать готовый элемент перед каждым обратным вызовом и вызвать его после команды удаления.Я также попытался реализовать удаление в beforeAll (), afterEach () и afterAll (), но все еще получаю противоречивые результаты.Я довольно озадачен этим.Я мог бы просто удалить ключ схемы вместе, но я хотел бы понять, что здесь происходит с beforeEach ().Спасибо заранее за любые советы.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Это может быть связано с тем, что вы на самом деле не используете API обещаний, который предлагает Мангуста.По умолчанию функции mongooses, такие как deleteMany(), не возвращают обещание.Вам нужно будет вызвать .exec() в конце цепочки функций, чтобы вернуть обещание e.g. await collection.deleteMany({}).exec().Итак, вы попадаете в состояние гонки.deleteMany() также принимает обратный вызов, поэтому вы всегда можете заключить его в обещание.Я бы сделал что-то вроде этого:

describe('API: /WT', () => {
  // Happy Path for Posting Object
  const wtEntry = {
    productType: 'A',
    waferId: 'A01A001.3',
    sublotId: 'A01A001.1',
  };

  beforeEach(async () => {
    await Wafer.deleteMany({}).exec();
  });

  describe('GET /:id', () => {
    it('Return Wafer Sort Entry with specified ID', async () => {
      expect.assertions(4);
      // Create a new wafer Entry and Save it to the DB
      const wafer = await Wafer.create(wtEntry);

      const res = await request(apiServer).get(`/WT/${wafer.id}`);
      expect(res.status).toBe(200);
      expect(res.body).toHaveProperty('productType', 'A');
      expect(res.body).toHaveProperty('waferId', 'A01A001.3');
      expect(res.body).toHaveProperty('sublotId', 'A01A001.1');
    });
}

Кроме того, всегда ожидайте утверждений с асинхронным кодом https://jestjs.io/docs/en/asynchronous.html

Подробнее об обещаниях mongoose и объектах запросов можно прочитать здесь https://mongoosejs.com/docs/promises.html

0 голосов
/ 24 октября 2018

Без удаления индекса схемы это, похоже, самое надежное решение.Не уверен на 100%, почему он работает над асинхронным ожиданием Wafer.deleteMany ({});

beforeEach((done) => {
    wtEntry = {
      productType: 'A',
      waferId: 'A01A001.3',
      sublotId: 'A01A001.1',
    };
    mongoose.connection.collections.promiswts.drop(() => {
      // Run the next test!
      done();
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...