Я хотел бы знать, как записать модульные тесты на модуль, который смешан в несколько классов, но не вполне знайте, как пойти об этом:
Я тестирую методы экземпляра путем записи тестов в одном из тестовых файлов для класса, который включает их (не кажется правильным), или можно ли так или иначе сохранить тесты для включенных методов в отдельном файле характерными для модуля?
Тот же вопрос относится к методам класса.
У меня должен быть отдельный тестовый файл для каждого из классов в модуле как нормальные модели направляющих, делают, или они живут в общем тестовом файле модуля, если это существует?
IMHO, вы должны выполнять функциональное тестовое покрытие, которое охватило все виды использования модуля, а затем проверять его в изоляции в модульном тесте:
setup do
@object = Object.new
@object.extend(Greeter)
end
should "greet person" do
@object.stubs(:format).returns("Hello {{NAME}}")
assert_equal "Hello World", @object.greet("World")
end
should "greet person in pirate" do
@object.stubs(:format).returns("Avast {{NAME}} lad!")
assert_equal "Avast Jim lad!", @object.greet("Jim")
end
Если ваши модульные тесты являются хорошими, вы должны быть в состоянии просто проверить тест Функциональность в модулях она смешана.
Написать тестовый помощник, который утверждает правильное поведение, затем используйте это против каждого класса, он смешан. Использование было бы следующим:
setup do
@object = FooClass.new
end
should_act_as_greeter
Если ваши модульные тесты хороши, это может быть просто Проверка дыма ожидаемого поведения, проверка правых делегатов и т. Д.
Не используйте сообщение для поиска. Поиск может быть благополучно сделать с Get, поскольку он ничего не изменит.
-121--2195374-Я, как правило, в целом проверил модуль как можно больше изоляции, по сути, проверяя методы, с достаточном кодом, издевателями и заглушками для его работы.
У меня, вероятно, также имели испытания на классы, в которые включены модули. Я не могу проверить каждый класс, но проведет достаточно классов, чтобы получить хорошее покрытие и иметь понимание любых проблем, которые возникают. Эти тесты не нужно явно проверить модуль, но, безусловно, будет тестировать его использование в частности сценарии.
Каждый набор испытаний будет иметь свой собственный файл.
Используйте встроенные классы (я не использую флексмак или stubba/mocha только для того, чтобы показать суть)
def test_should_callout_to_foo
m = Class.new do
include ModuleUnderTest
def foo
3
end
end.new
assert_equal 6, m.foo_multiplied_by_two
end
Любая издевательская библиотека/нарезка должна дать вам более чистый способ сделать это. Также вы можете использовать structs:
instance = Struct.new(:foo).new
class<<instance
include ModuleUnderTest
end
instance.foo = 4
Если у меня есть модуль, который используется во многих местах, у меня есть юнит-тест для него, который делает именно это (сдвиньте тестовый объект под модульные методы и проверьте, корректно ли работают модульные методы на этом объекте).
Я пытаюсь сохранить свои тесты, сосредоточенные только на договоре к этому конкретному классу / модулю Отказ Если я доказал, что поведение модуля в классе тестирования для этого модуля (обычно, включая этот модуль в тестовом классе, объявленном в спецификации для этого модуля), то я не буду дублировать этот тест для класса производства, который использует этот модуль. Но если есть дополнительное поведение, которое я хочу проверить для класса производства, или проблемы интеграции, я напишу тесты для класса производства.
Например, у меня есть модуль под названием Attributevalidator
, который выполняет легкие валидации в виде аналогичных ActiveRecord
. Я пишу тесты для поведения модуля в спецификации модуля:
before(:each) do
@attribute_validator = TestAttributeValidator.new
end
describe "after set callbacks" do
it "should be invoked when an attribute is set" do
def @attribute_validator.after_set_attribute_one; end
@attribute_validator.should_receive(:after_set_attribute_one).once
@attribute_validator.attribute_one = "asdf"
end
end
class TestAttributeValidator
include AttributeValidator
validating_str_accessor [:attribute_one, /\d{2,5}/]
end
Теперь в классе производства, который включает в себя модуль, я не буду подтвердить, что обратные вызовы сделаны, но я могу утверждать, что включенный класс имеет определенную проверку Установите с определенным регулярным выражением, что-то особенное для этого класса, но не воспроизводя тесты, которые я написал для модуля. В спецификации для класса производства я хочу гарантировать, что конкретные валидации устанавливаются, но не при этом валидации работают в целом. Это своего рода тест интеграции, но тот, который не повторяет те же утверждения, которые я сделал для модуля:
describe "ProductionClass validation" do
it "should return true if the attribute is valid" do
@production_class.attribute = @valid_attribute
@production_class.is_valid?.should be_true
end
it "should return false if the attribute is invalid" do
@production_class.attribute = @invalid_attribute
@production_class.is valid?.should be_false
end
end
здесь есть некоторая дублирование здесь (поскольку большинство интеграционных тестов будут иметь), но тесты доказывают две разные вещи для меня Отказ Один набор тестов доказывает общее поведение модуля, другой доказывает конкретные проблемы реализации производственного класса, который использует этот модуль. Из этих тестов я знаю, что модуль будет проверять атрибуты и выполнять обратные вызовы, и я знаю, что мой класс производства имеет определенный набор валидаций для конкретных критериев, уникальных для класса производства.
Надеюсь, что поможет.