Стучать и/или издеваться над классом в sinon.js?

Я создал оболочку базы данных для моего приложения, как показано ниже. Чтобы проверить это, я, очевидно, хотел бы заменить фактическую библиотеку базы данных. Я мог бы создать новый класс, который издевается над методом query и поймает все входные данные там, но использование sinon.js кажется более подходящим, но как я могу его использовать?
Являются функциями mock или stub sinon.js, что я должен использовать?

wrapper = (function() {

  function wrapper() {}

  wrapper.db = require("database");

  wrapper.prototype.insertUser = function(doc) {
    return this.db.query("INSERT INTO USERS...");
  };

  return wrapper;

})();

Ответ 1

Вы можете использовать оба для этого.

Mock имеют ожидаемое упорядоченное поведение, которое, если не следовать правильно, приведет к ошибке.

A Stub похож на макет, но без порядка, поэтому вы можете называть свои методы так, как вы хотите. По моему опыту вы почти никогда не нуждаетесь в макете.

Оба из них заменят ваш метод на пустой метод или закрытие, если вы его передадите. Это будет примерно так:

stub = sinon.stub(wrapper , 'insertUser ', function () { return true; });

Затем вы добавляете поведение ожидания, чтобы проверить, произошло ли это.

Мне нравится использовать Jasmine с Jasmine-Sinon для проверки тестов.

Ответ 2

Во-первых, я немного изменил бы определение класса (имя верхнего регистра и исправить назначение db):

var Wrapper = (function() {

  function Wrapper() {
    this.db = require("database");
  }

  Wrapper.prototype.insertUser = function(doc) {
    return this.db.query("INSERT INTO USERS...");
  };

  return Wrapper;

})();

Чтобы заглушить весь класс:

var WrapperStub = sinon.spy(function() {
  return sinon.createStubInstance(Wrapper);
});

sinon.createStubInstance создаст экземпляр Wrapper, где каждый метод является заглушкой. sinon.spy позволит нам искать экземпляр класса.

Итак, вы можете это сделать так:

// verify instantiation
var wrapper = new WrapperStub();
expect(WrapperStub).to.have.been.calledWithNew;

// verify method stub
wrapper.insertUser.returns('data');
expect(wrapper.insertUser()).to.equal('data');
expect(wrapper.insertUser).to.have.been.calledOnce;

(утверждения используют chai и sinon-chai)

Я сказал просто "упражнение", потому что этот фрагмент кода не является фактическим unit test. Мгновенные вызовы и вызовы методов будут выполняться вашим испытуемым.

Теперь, если вы хотите высмеять зависимость, введенную require(), например, db = require('database') в вашем примере, вы можете попробовать инструмент для тестирования, например Jest (но не используя синус) или sinonquire, который я создал, вдохновленный Jest но использовать его с синоном плюс ваш любимый инструмент тестирования (мой мокко). Внутри sinonquire использует тот же метод, который показан выше, для объединения sinon.spy и sinon.createStubInstance, чтобы заглушить класс.