Как стать автором
Обновить

BDD/TDD — Учимся писать матчеры

Время на прочтение3 мин
Количество просмотров4.2K
Разработка, основанная на&nbspспецифицировании поведения (BDD), — один из краеугольных камней философии Ruby.

Очень удачной реализацией BDD является всем знакомый RSpec. Одной из замечательных черт RSpec является его расширяемость.

Так, мы используем RSpec совместно с Factory Girl (хотя стоило бы перейти на Machinist), RR (прекрасный каркас для заглушек), Spork и недавно перешли с Shoulda на Remarkable.

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

Хорошим способом сделать это является создание нового «ожидателя» (matcher).



Основная логика заключается в методе is_valid?, который проверяет соответствие субьекта тестирования нашим ожиданиям.

  1. module Scalaxy
  2.   module Matchers
  3.     class CallbackPresenceMatcher < Remarkable::Base
  4.       arguments :chain, :callback
  5.       assertion :is_valid?
  6.     protected
  7.       def is_valid?
  8.         instance = @subject.kind_of?(Class) ? @subject.new : @subject
  9.         chain_name = "#{@chain}_callback_chain".to_sym
  10.         return false unless instance.kind_of?(ActiveSupport::Callbacks)
  11.         return false unless instance.class.respond_to?(@chain)
  12.         return false unless instance.class.respond_to?(chain_name)
  13.         return false if instance.class.send(chain_name).select { |c| c.method == @callback }.empty?
  14.         true
  15.       end
  16.     end
  17.     # Matches for presence of specified callback inside specified callback chain.
  18.     # should_callback_presence :after_run, :notify_people
  19.     def callback_presence(*args)
  20.       CallbackPresenceMatcher.new(*args).spec(self)
  21.     end
  22.   end
  23. end
  24. Remarkable.include_matchers!(Scalaxy, ActiveSupport::TestCase)


Также потребуется расширить файл локали, добавив в него информацию о нашем «ожидателе».
  1. en:
  2.   scalaxy:
  3.     callback_presence:
  4.       description: 'Checks for presence of {{callback}} in specified callback chain {{chain}}.'
  5.       expectations:
  6.         is_valid: "to be valid when {{callback}} in {{chain}}"


И добавить require на наш файл matchers.rb в spec_helper.

И теперь можно легко и просто описывать наши ожидания.
  1. class Thing < ActiveRecord::Base
  2.   ## Callbacks
  3.   define_callbacks :after_run
  4.   after_run :notify_people
  5. end

  1. describe Thing do
  2.   should_callback_presence :after_run, :notify_people
  3. end


______________________
Текст подготовлен в Хабра Редакторе от © SoftCoder.ru
Теги:
Хабы:
Всего голосов 22: ↑18 и ↓4+14
Комментарии15

Публикации

Истории

Работа

Программист Ruby
8 вакансий
Ruby on Rails
7 вакансий

Ближайшие события