Как построить цепочечные методы, такие как - should_receive (: что-то) .with (: параметры, значения) .and_return (: что-то - PullRequest
0 голосов
/ 02 июня 2011

Я пытался сделать мой код немного меньше, создавая метод, который может выглядеть как must_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')

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

Ответы [ 3 ]

2 голосов
/ 02 июня 2011

Простой:

class Obj
  def should_receive(msg)
    self.send(msg.to_sym)
    self
  end
  def and_transition_to(state)
    @state == state
  end
  def add
    @state = 'adding'
  end
end  

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

obj = Obj.new
obj.should_receive(:add).and_transition_to('adding')
=> true
0 голосов
/ 03 июня 2011

Важной частью цепочки является возврат 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
0 голосов
/ 02 июня 2011

Это не 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;
    }
    :
...