тестирование изоляции контроллера от моделей - PullRequest
0 голосов
/ 31 марта 2012

Возможно ли (и разумно) написать тесты и классы Controller перед написанием базовых классов Model?Я думал, что видел заметки о том, как это сделать, но теперь я не могу найти рецепт.

Например, рассмотрим следующий контроллер:

# file: app/controllers/premises_controller.rb
class PremisesController < ApplicationController

  def create
    @premise = Premise.new(params[:premise])
    respond_with @premise
  end

end

Могу ли я проверить этот код контроллераперед созданием базовой модели помещения и помещения?Я знаю, что следующее не сработает - как бы вы переписали это (если это возможно)?

# file: spec/controller/premise_spec.rb
require "spec_helper.rb"

describe PremisesController do
  context 'POST create' do
      it 'should assign a new Premise to @premise' do
        premise = stub_model(Premise)
        Premise.stub(:create) { premise }
        post :create
        assigns(:premise).should == premise
      end
    end
  end
end

update

Чем больше я об этом думаю, тем больше я 'Я убежден, что мне нужно нужно определить класс Premise - код PremisesController должен ссылаться на него.Поэтому я изменю свой вопрос на «необходимо ли создать базовую таблицу базы данных premises для выполнения PremisesController тестов?»

На данный момент я не вижу хорошего способавокруг него (без изменения кода PremisesController, который побеждает точку тестирования).Например, вызов respond_with вызывает @premise.has_errors?, который, в свою очередь, обращается к базе данных, чтобы получить имена столбцов.Если я не захочу заглушить методы, внутренние по отношению к ActiveRecord, я не вижу, как избежать попадания в БД.

Но я бы с радостью показал, что иначе.

Ответы [ 2 ]

0 голосов
/ 01 апреля 2012

Ладно - я смирился с этим: нецелесообразно создавать какие-либо значимые тесты, если таблица базы данных не существует - слишком много битов ActiveRecord зависит от определения таблицы.

Но это не мешает писать тест с чистым разделением между контроллером и моделью. Об этом красноречиво говорит Сам Дчелимский в этом выпуске RSpec . Суть его поста:

  • Тестирование с использованием интеграционного теста в spec / запросы / premise_spec.rb, который выдает get и проверяет сгенерированный ответ json.
  • При использовании метода тощего контроллера (например, показанного в OP) не беспокойтесь о написании теста контроллера.
  • Напишите тесты модели, чтобы убедиться, что модель испускает правильный json.

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

0 голосов
/ 31 марта 2012

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

class PremisesController < ApplicationController
  def create
    @premise = premise_until_model_finished params[:premise]
    respond_with @premise
  end

  def premise_until_model_finished premise
    Premise.new premise
  end
end


require "spec_helper.rb"

describe PremisesController do
  context 'when creating a premise' do
    before :each do        
      @my_fake_model = { 
        :some_attribute => 'funk', 
        :some_other_attribute => 'a-delic'
      }
      PremisesController.any_instance.stub( :premise_until_model_finished).and_return(
        @my_fake_model 
      )
      PremisesController.any_instance.should_receive( 
        :premise_until_model_finished
      ).and_return( @my_fake_model )
      post :create
    end

    it 'should create a premise as expected' do
      # your criteria here...
    end
  end
end
...