как написать rspec для метода

У меня есть следующий код в папке программируемости

module Programmability
  module Parameter
    class Input < Parameter::Base
      attr_reader :args

  def initialize(name, type, **args)
    super(name, type)
    @args = args
  end

  def value=(val)
    if val
      val = convert_true_false(val)
--- some code ----
    end
    @value = val
  end      


  def convert_true_false(val)
    return val unless @args[:limit] == 1
    if [:char].include?(@type) && val == 'true'
      'Y'
    elsif [:char].include?(@type) && val == 'false'
      'N'
    elsif [:bit].include?(@type) && val == 'true'
      1
    elsif [:bit].include?(@type) && val == 'false'
      0
    end
  end
end
  end
end

Я пытаюсь написать rspec для метода convert_true_false. Я новичок в rspec. любая помощь приветствуется.

я пытался сделать это

   context 'returns Y if passed true'
    input = Programmability::Parameter::Input.new(name, type, limit)

      it 'returns Y' do
        name = 'unregister_series'
        type = ':char'
        limit = 1

        expect(input.value = 'true' ).to eq('Y')
      end
  end

но не набирает предельное значение. когда он достигает метода convert_true_false, он выходит из него, поскольку @args[:limit] равен нулю

Спасибо


person User7354632781    schedule 29.03.2017    source источник
comment
Вы пробовали что-нибудь?   -  person ndnenkov    schedule 29.03.2017
comment
да обновленный вопрос   -  person User7354632781    schedule 29.03.2017
comment
Можете ли вы добавить в свою спецификацию код, который создал input?   -  person ndnenkov    schedule 29.03.2017
comment
жаль пропустил это. добавлен   -  person User7354632781    schedule 29.03.2017
comment
args являются аргументами ключевого слова. Следовательно, вы должны сделать Input.new(name, type, limit: limit). Он вообще не должен позволять вам создавать объект.   -  person ndnenkov    schedule 29.03.2017
comment
Да, ты прав. позвольте мне попробовать ваше решение   -  person User7354632781    schedule 29.03.2017
comment
@ndn Это не аргументы ключевого слова, это хэш-значения. Есть явная разница.   -  person Dave Newton    schedule 29.03.2017
comment
@DaveNewton, это kwargs (аргументы ключевого слова переменной длины).   -  person ndnenkov    schedule 29.03.2017
comment
функция convert_true_false не будет возвращать val = 'Y'. есть идеи, что не так? я ставлю byebug и получаю (byebug) @args[:limit] 1 (byebug) @type :char (byebug) val true   -  person User7354632781    schedule 29.03.2017
comment
@ User7354632781, для начала, что он вернул. Распечатайте это. Также распечатайте результат вызова convert_true_false.   -  person ndnenkov    schedule 29.03.2017
comment
@ndn Я думаю, хотя я не вижу большой практической разницы - вы получаете хэш обратно.   -  person Dave Newton    schedule 29.03.2017
comment
Я вижу, что convert_true_false возвращает Y, помещая byebug, но ожидается сбой теста: Y получил: true is expect(input.value = 'true').to eq('Y') неправильно?   -  person User7354632781    schedule 29.03.2017
comment
@DaveNewton, есть много различий, слишком много для одного комментария. Я уверен, что вы можете найти статью на эту тему или уже знаете некоторые из них. Но важно также сделать концептуальную разницу. Я считаю, что устаревшая альтернатива хеша в качестве последнего параметра почти работает как kwargs, которые у нас были до Ruby 2.0, как один из недостатков языка.   -  person ndnenkov    schedule 29.03.2017
comment
@ User7354632781, добавил ответ.   -  person ndnenkov    schedule 29.03.2017
comment
@ndn Я этого не делал; это был простой обходной путь для отсутствующей языковой функции. ¯(°_o)/¯   -  person Dave Newton    schedule 29.03.2017
comment
Можете ли вы напрямую назначить его? @value = convert_true_false (val)?   -  person ndnenkov    schedule 29.03.2017


Ответы (1)


Проблема в том, что сеттеры всегда возвращают переданное значение:

class Test
  def foo=(foo)
    @foo = foo + 100
    return 42
  end
end

puts (Test.new.foo = 69) # 69

Чтобы решить эту проблему, просто проверьте значение после того, как вы его присвоили:

# instead of
expect(input.value = 'true').to eq 'Y'

# do
input.value = 'true'
expect(input.value).to eq 'Y'
person ndnenkov    schedule 29.03.2017
comment
input возвращает ‹Programmability::Parameter::Input:0x007f99573785a0 @name=unregister_series, @type=:char, @args={:limit=›1}, @value=Y, поэтому я ожидал(input.value).to eq ('Y'), но ожидается ошибка: Y got: N'Y' - person User7354632781; 29.03.2017