Тест контроллера CodeShip rspec не пройден

Я пытаюсь сделать мое приложение готовым к использованию через CodeShip.

Он прекрасно работает при использовании Travis CI (за исключением некоторых интеграционных тестов, но это уже другая история) и, конечно, на моей локальной машине. Однако тот же код не может быть проверен только в одном определенном месте, если CodeShipping. Я бы не удивился, если бы сбой был связан с тестированием функций, но он не удался в спецификации контроллера!

Ошибка CodeShip:

Failures:

1) ParrotsController GET #index with filters returns by id
Failure/Error: expect(json.count).to eq 1

  expected: 1
       got: 0

  (compared using ==)

# ./spec/controllers/parrots_controller_spec.rb:117:in `block (4 levels) in <top (required)>'

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

Команды настройки CodeShip:

npm install -g bower
bower install
rvm use 2.2.3 --install
bundle install
export RAILS_ENV=test
bundle exec rake db:migrate --trace
bundle exec rake db:test:prepare
bundle exec rake db:schema:load

Тестовые команды CodeShip:

export CODECLIMATE_REPO_TOKEN=blahblah
xvfb-run -a bundle exec rspec spec

Код действия

def index
  # TODO Below code is not ideal, needs optimizing
  begin

    p = Parrot.all # I could use @parrots everywhere, but 'p' is shorter for bunch of selects

    [:ancestors, :descendants, :children, :parents].each do |selector|
      (p = p & Parrot.find(params[selector].to_i).try(selector)) if params[selector]
    end

    # Temporary solution for nil elements within 'p' when wrong 'selector' ids given
    p.each { |_p| p.delete _p if _p.nil? } if p

    (p = p.select { |_p| _p.age    >= params[:age_min].to_i }) if params[:age_min]
    (p = p.select { |_p| _p.age    <= params[:age_max].to_i }) if params[:age_max]
    (p = p.select { |_p| _p.sex    == params[:sex] })          if params[:sex]
    (p = p.select { |_p| _p.id     == params[:id].to_i })      if params[:id]
    (p = p.select { |_p| _p.tribal == (params[:tribals] == 'true' || params[:tribal] == true) }) unless params[:tribals].nil?
    (p = p.select { |_p| _p.color  == Color.find_by_name(params[:color]) })   unless params[:color].blank?
    (p = p.select { |_p| _p.name.downcase.include?(params[:name].downcase) }) unless params[:name].blank?

    @parrots = p

  rescue Exception => e
    @error = e
  end

  respond_to do |format|
    format.json do
      render layout: false, status: (@error ? :unprocessable_entity : :ok)
    end
  end
end

index.json.jbuilder

if @error
  json.error @error.to_s
else
  json.array! @parrots, :id, :name, :age, :color_id, :sex, :tribal, :color_hex
end

Тестовый код

describe 'GET #index' do
  before do
    @grandmother = create(:parrot, name: 'FooMother', age: 40, sex: 'female', tribal: true, color_name: 'green')
    @grandfather = create(:parrot, name: 'FooFather', age: 50, sex: 'male', tribal: true, color_name: 'green')
    @mother = create(:parrot, name: 'Foo', age: 20, sex: 'female', tribal: true, color_name: 'red', father_id: @grandfather.id, mother_id: @grandmother.id)
    @father = create(:parrot, name: 'Bar', age: 30, sex: 'male', tribal: true, color_name: 'red')
    @son = create(:parrot, name: 'FoobarSon', age: 3,  sex: 'male', tribal: true, color_name: 'green', father_id: @father.id, mother_id: @mother.id)
    @daughter = create(:parrot, name: 'FoobarDaughter', age: 5, sex: 'female', tribal: false, color_name: 'blue', father_id: @father.id, mother_id: @mother.id)
  end

  context 'no filters' do
    it ' returns all' do
      get :index, format: :json
      expect(json.count).to eq 6
    end
  end

  context 'with filters' do
    it 'returns older than' do
      get :index, format: :json, age_min: 20
      expect(json.count).to eq 4
      expect(json.collect{ |p| p['id'] }).to include @grandmother.id
    end

    it 'returns younger than' do
      get :index, format: :json, age_max: 30
      expect(json.count).to eq 4
      expect(json.collect{ |p| p['id'] }).to_not include @grandmother.id
    end

    it 'returns with age in range' do
      get :index, format: :json, age_min: 20, age_max: 40
      expect(json.count).to eq 3
      expect(json.collect{ |p| p['id'] }).to_not include @grandfather.id
      expect(json.collect{ |p| p['id'] }).to_not include @son.id
    end

    it 'returns by id' do # todo doesn't pass in CodeShip only. Why?!
      get :index, format: :json, id: 2
      expect(json.count).to eq 1
      expect(json.collect{ |p| p['name'] }).to include @grandfather.name
    end

    # Other tests...
  end
end

0 ответов

Другие вопросы по тегам