Как создавать связанные методы, такие как — should_receive(: something).with(: параметры, значения).and_return(:something_else)

#ruby-on-rails #ruby #rspec #rspec-rails

#ruby-on-rails #ruby #rspec #rspec-rails

Вопрос:

Я пытался сделать свой код немного меньше, создавая метод, который может выглядеть как should_receive из RSpec, случай здесь в том, что я тестирую конечный автомат, и у меня есть несколько методов с кодом, подобным этому:

 context "State is unknown" do
  before do
    @obj = create_obj(:state => 'unknown')
  end
  context "Event add" do
    it 'should transition to adding if not in DB' do
      @obj.add
      @obj.state.should == 'adding'
    end

    it 'should transition to linking if already in DB' do
      create_obj_in_db
      @obj.add
      @obj.state.should == 'linking'
    end
  end
end
  

Я хочу заменить эти строки кода на что-то похожее на это:

 @obj.should_receive(:add).and_transition_to('adding')
@obj.should_receive(:modify).and_transition_to('modifying')
  

Как создаются эти методы?

Ответ №1:

Простой:

класс Obj 
 def should_receive(сообщение)
 self.send(msg.to_sym)
 self 
конец 
 def и_transition_to(состояние)
 @state == состояние 
конец 
 def добавить 
 @state = 'добавление'
 конец 
конец 

Теперь вы можете запустить:

obj = Obj.new 
obj.should_receive(:добавить).and_transition_to('добавление')
=> true

Ответ №2:

Важной частью цепочки является возврат self из объекта, чтобы следующий вызов все еще мог работать с объектом.

 class Foo
  def one
    puts "one"
    self
  end

  def two
     puts "two"
     self
  end

  def three
     puts "three"
     self
  end
end

a=Foo.new
a.one.two.three
  

Ответ №3:

Это не ruby-on-rails, но в этой статье приведен пример свободного интерфейса.

 public class Pipeline
{
    private Image image;
    public Image CurrentImage
    {
        get { return image; }
        set { image = value; }
    }

    public Pipeline(string inputFilename)
    {
        image = Bitmap.FromFile(inputFilename);
    }

    public Pipeline Rotate(float Degrees)
    {
        RotateFilter filter = new RotateFilter();
        filter.RotateDegrees = Degrees;
        image = filter.ExecuteFilter(image);
        return this;
    }
    :