2016-09-21 5 views
1

Итак, я довольно новичок в Rspec, и я пытаюсь понять, как писать тесты для класса, который принимает объект как параметр конструктора и устанавливает это объект переменной экземпляра. Затем он вызывает методы объекта объекта экземпляра другими способами.RSpec тестирование класса, который использует объект gem как переменную экземпляра

Пример:

class ClassA 
    def initialize(string_object, gem_object) 
    @instance_variable1 = gem_object 
    @string = string_object 
    end 

    def check_validity?(some_arg) 
    unless @instance_variable1.gemObjectMethod1.gemObjectMethod2(some_arg).empty? 
     return true 
    end 
    false 
    end 
    .. 
    .. 
end 

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

Для следующего метода, что я пытался в этот момент является:

describe '#check_validity?' do 
    context 'gets empty list' do 
    let (:actual) { subject.check_validity?("sample") } 
    before do 
     allow(subject).to receive(@instance_variable1.gemObjectMethod1.gemObjectMethod2).with("sample").and_return([]) 
    end 
    it 'returns false' do 
     expect(actual).to be false 
    end 
    end 
end 

Но это дает мне ошибку, относящемуся к моему конструктору говоря, что он ожидал 2 аргумента, но был дан 0.

Любая помощь приветствуется! Кроме того, я не мог найти ничего, что можно было бы описать конструкторами с издевательством их аргументов. Возможно, я искал не то место или, возможно, пропустил что-то очевидное, так как это мой первый опыт работы с BDD.

ответ

1

В RSpec «прием» - это метод, который принимает символ, который представляет имя метода. (Это позволяет цепной а «с» методом, который принимает ожидаемый список параметров.) Для того, чтобы исправить до того, блок, который Вы можете сделать это:

before do 
    allow(subject.instance_variable_get(:@instance_variable1).gemObjectMethod1).to receive(:gemObjectMethod2).with("sample").and_return([]) 
end 

Явным уродство, что, однако, предполагает, что что-то неправильно. И это. Код сильно нарушает law of demeter, и тест втягивается в него.

В качестве первой попытки очистить его можно рассмотреть метод, который «кэширует» результаты вызова @ instance_variable1.gemObjectMethod1. Предположим, что этот первый метод возвращает перечислимую группу виджетов. Вы можете изменить свой класс, чтобы включить что-то вроде этого:

def check_validity(a_string) 
    widgets.gemObjectMethod2(a_string).empty? 
end 

private 

def widgets 
    @widgets ||= @instance_variable1.gemObjectMethod1 
end 

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

let(:gem_widgets) do 
    instance_double(GemObjectMethod1ResultClass, gemObjectMethod2: true) 
end 

before do 
    allow(subject).to receive(:widgets).and_return(gem_widgets) 
    allow(gem_widgets).to receive(:gemObjectMethod2).with("sample"). 
    and_return([]) 
end 

it 'should pass with "sample"' do 
    expect(actual).to eql true 
end 
+0

Спасибо, это было полезно. Есть ли у вас предложение по тестированию конструктора? Я думал о тестировании того, что объект не существует до вызова new, а затем он делает это и имеет правильные переменные экземпляра. Я говорю о том, как проверить, был ли объект создан или нет. – marauder7

+0

То, что я часто делаю с такими классами, это сделать доступными переменные экземпляра через считыватели атрибутов (например, attr_reader: string_object,: gem_object в верхней части ClassA). Если вы это сделаете, то тестирование назначения довольно просто - проверьте значение метода getter после создания экземпляра. – AndyV

+0

Спасибо. Однако, у меня есть вопрос. Создав метод widgets, не нужно ли мне точно узнать, что возвращает gemObjectMethod1 и не противоречит принципу абстракции? – marauder7

Смежные вопросы