Пересмешивать базу данных в node.js?

Как бы я смоделировал базу данных в моем приложении node.js, которое в этом случае использует mongodb как бэкэнд для блога REST API?

Конечно, я мог бы установить базу данных для конкретного testing -database, но я все равно буду сохранять данные и проверять не только свой код, но и базу данных, поэтому я на самом деле не занимаюсь модульным тестированием, а интеграционным тестированием.
Так что же делать? Создать обертки базы данных в качестве промежуточного уровня между приложением и базой данных и заменить DAL при тестировании?

// app.js  
var express = require('express');
    app = express(),
    mongo = require('mongoskin'),
    db = mongo.db('localhost:27017/test?auto_reconnect');

app.get('/posts/:slug', function(req, res){
    db.collection('posts').findOne({slug: req.params.slug}, function (err, post) {
        res.send(JSON.stringify(post), 200);
    });
});

app.listen(3000);

// test.js
r = require('requestah')(3000);
describe("Does some testing", function() {

  it("Fetches a blogpost by slug", function(done) {
    r.get("/posts/aslug", function(res) {
      expect(res.statusCode).to.equal(200);
      expect(JSON.parse(res.body)["title"]).to.not.equal(null);
      return done();
    });

  });
));

6 ответов

Решение

Я не думаю, что код, связанный с базой данных, можно должным образом протестировать без тестирования с помощью программного обеспечения базы данных. Это потому, что код, который вы тестируете, - это не только JavaScript, но и строка запроса к базе данных. Даже если в вашем случае запросы выглядят простыми, вы не можете полагаться на то, что так будет всегда.

Таким образом, любой уровень эмуляции базы данных обязательно будет реализовывать всю базу данных (возможно, за вычетом дискового пространства). К тому времени вы заканчиваете интеграционным тестированием с эмулятором базы данных, даже если вы называете это модульным тестированием. Другим недостатком является то, что эмулятор базы данных может иметь другой набор ошибок по сравнению с базой данных, и вам может понадобиться кодировать как эмулятор базы данных, так и базу данных (что-то вроде ситуации с IE против Firefox против Chrome и т. Д.).).

Поэтому, на мой взгляд, единственный способ правильно протестировать ваш код - это связать его с реальной базой данных.

Существует общее правило, когда дело доходит до насмешек,

Не издевайтесь над тем, что вам не принадлежит.

Если вы хотите смоделировать базу данных, спрячьте ее с помощью абстрагированного сервисного слоя и смоделируйте этот слой. Затем убедитесь, что вы тестируете интеграцию реального уровня сервиса.

Лично я отказался от использования макетов для тестирования и использовал их для проектирования сверху вниз, помогая мне по мере продвижения вести разработку сверху-вниз по макетам сервисных уровней, а затем, в конечном итоге, реализовывать эти уровни и писать интеграционные тесты. Используемые в качестве инструмента тестирования, они, как правило, делают ваш тест очень хрупким и в худшем случае приводят к расхождению между реальным поведением и поддельным поведением.

Я не согласен с выбранным ответом или другими ответами до сих пор.

Разве не было бы замечательно, если бы вы могли отлавливать ошибки, порожденные хаотичными и много раз грязными изменениями, вносимыми в схемы БД и ваш код, ДО того, как он попадет в QA? Бьюсь об заклад, большинство будет кричать, черт возьми, да!

Вы, безусловно, можете и должны изолировать и протестировать схемы БД. И вы не делаете это на основе эмулятора или тяжелого образа или воссоздания вашей БД и машины. Вот что такое, как SQLite, просто для примера. Вы имитируете его на основе легкого запущенного экземпляра в памяти и статических данных, которые не изменяются в этом экземпляре в памяти, что означает, что вы действительно тестируете свою БД изолированно и можете доверять своим тестам. И, очевидно, это быстро, потому что он в памяти, скелете, и в конце теста запускается.

Так что да, вы должны и должны протестировать SCHEMA, который экспортируется в очень легкий в памяти экземпляр любого используемого вами механизма / среды выполнения БД, и что вместе с добавлением очень небольшого количества статических данных становится вашей изолированной макетированной БД.

Вы периодически экспортируете свои реальные схемы из вашей реальной БД (в автоматическом режиме) и импортируете / обновляете их в свой экземпляр БД с подсветкой перед каждым нажатием на QA, и вы сразу узнаете, были ли какие-либо последние изменения БД, сделанные вашими администраторами БД или другими разработчики, которые изменили схему в последнее время, сломали любые тесты.

Хотя я приветствую попытку сделать все возможное, чтобы ответить, я бы проголосовал против нынешнего ответа, если бы мог, но я новичок и еще не набрал достаточно репутации, чтобы позволить себе это сделать.

Что касается человека, который ответил: "Не издевайтесь над тем, чем не владеете". Я думаю, что он хотел сказать "не проверяй ничего, чем не владеешь". Но вы ДЕЙСТВИТЕЛЬНО издеваетесь над вещами, которыми не владеете! Потому что это те вещи, которые не тестируются, и их нужно изолировать!

Я планирую поделиться с вами КАК и обновлю этот пост в будущем с помощью реального примера кода JS!

Это то, что постоянно делают многие тестируемые команды. Вы просто должны понять, как.

Мой предпочтительный подход к модульному тестированию кода БД на любом языке заключается в доступе к Mongo через абстракцию репозитория (пример здесь http://iainjmitchell.com/blog/?p=884). Реализации будут различаться в зависимости от конкретной функциональности БД, но, удалив весь код Mongo из вашей собственной логики, вы сможете приступить к модульному тестированию. Просто замените реализацию репозитория Mongo на заглушенную версию, которая тривиально проста. Например, просто храните объекты в простой коллекции словаря в памяти.

Таким образом, вы получите преимущества модульного тестирования своего собственного кода без зависимостей от БД, но вам все равно придется проводить интеграционные тесты с основной БД, потому что вы, вероятно, никогда не сможете эмулировать идиосинкразии реальной базы данных, как это делают другие. сказал здесь. Виды вещей, которые я обнаружил, так же просты, как индексирование в безопасном режиме по сравнению с безопасным режимом. В частности, если у вас есть уникальный индекс, ваша фиктивная реализация памяти может соблюдать это во всех случаях, но Mongo не обойдется без безопасного режима.

Поэтому, несмотря на то, что вам все равно нужно будет проводить тестирование на базе данных для некоторых операций, вы наверняка сможете правильно протестировать свою собственную логику с помощью заглушенной реализации Repository.

Цель насмешек - пропустить сложность и выполнить модульное тестирование собственного кода. Если вы хотите написать тесты e2e, используйте db.

Написание кода для настройки / демонтажа тестовой БД для модульного тестирования - техническая задолженность и невероятно неудовлетворительная.

В npm есть фиктивные библиотеки:

Монго - https://www.npmjs.com/package/mongomock

мангуст - https://www.npmjs.com/package/mockgoose

Если они не поддерживают необходимые вам функции, то да, возможно, вам придется использовать реальную вещь.

У меня была эта дилемма, и я решил работать с тестовой БД и очищать ее каждый раз, когда начинается тест. (как все бросить: /questions/38662176/udalit-vse-v-baze-dannyih-mongodb/38662190#38662190)

С помощью NPM вы даже можете создать тестовый скрипт, который создает файл db и очищает его после.

Другие вопросы по тегам