запуск модульных тестов Rails без загрузки среды или использования базы данных

В качестве академического упражнения я подумал, что попытаюсь запустить свои модульные тесты, не загружая среду Rails (или не обращаясь к базе данных).

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

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


person whatbird    schedule 16.08.2011    source источник


Ответы (3)


Полезная ссылка: тестирование Rails без Rails

Тестирование без базы данных потребует много макетов и заглушек, добавить особо нечего.

person apneadiving    schedule 16.08.2011

Проверьте NullDB. Я имел смешанный успех с ним.

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

person vladiim    schedule 24.04.2012
comment
Похоже, что NullDB уделялось много внимания, и только с одной открытой проблемой, похоже, он хорошо работает в тандеме с CI. - person DBrown; 30.11.2017

Альтернативный подход к написанию приложения немного по-другому.

Извлеките всю важную логику, которую вы хотите протестировать, в классы ruby ​​без зависимостей от базы данных.
Пишите тесты только для этих классов — ваши тесты будут работать! :)

Например

ProductQuantity = Struct.new(:product_id, :quantity)

class Customer < ActiveRecord
  def create_order(product_quantities)
    product_ids = product_quantities.map(&:product_id)
    products = Product.where(:id => product_ids).pluck(:id, unit_price).to_h

    total = product_quantities.reduce(0) do |sum, p|
      sum += p.quantity * products.fetch(p.product_id, 0)
    end

    Order.create!(:customer_id => id, :total => total)
  end
end

Извлечение бизнес-логики из зависимостей базы данных

class Customer < ActiveRecord
  def create_order(product_quantities)
    products = Product.where(:id => product_ids).pluck(:id, unit_price).to_h

    total = CalculateNewOrderTotal.from(products, product_quantities)

    Order.create!(:customer_id => id, :total => total)
  end
end

module CalculateNewOrderTotal
  def self.from(products, product_quantities)
    product_quantities.reduce(0) do |sum, p|
      sum += p.quantity * products.fetch(p.product_id, 0)
    end
  end
end

Теперь модуль CalculateNewOrderTotal может быть полностью покрыт очень быстрыми тестами, которые не требуют макетов или фактической базы данных.

Вы по-прежнему можете писать тесты счастливого пути с реальной базой данных для метода Customer.create_order.

Дополнительные преимущества

Ваша бизнес-логика не зависит от структуры постоянства.
Ваша бизнес-логика не зависит от схемы сохранения. Вы можете изменить способ хранения данных, не затрагивая важный код бизнес-логики.
Никаких имитаций
Никаких дополнительных слоев. абстракций — вы по-прежнему можете использовать все преимущества ActiveRecord, например, обернуть вызов метода транзакцией.
Никакие другие фреймворки или гемы не задействованы — чистый ruby ​​и RSpec или тестовый фреймворк по вашему выбору :)

person Fabio    schedule 28.10.2020