2015-07-08 4 views
3

EDIT: В соответствии с предложением @max, я меняю модель, чтобы использовать enum вместо этого, однако я не могу проверить ее для состояния по умолчанию:Как получить спецификацию теста для модели с типом поля перечисления - Mongoid

it { is_expected.to validate_inclusion_of(:status).to_allow("draft", "published") } 

прекрасно работает со следующим кодом в модели:

validates :status,  :inclusion => { :in => ["draft", "published"] } 

Но эта часть до сих пор не удается:

it { is_expected.to have_field(:status).with_default_value_of("draft") } 

Обратите внимание, что я использую Mongoid. У меня это в моей спецификации модели:

OLD вопрос - сохранен для справки?

it { is_expected.to have_field(:published).of_type(Boolean).with_default_value_of(false) } 

И в моей модели у меня есть это:

field :published,   type: Mongoid::Boolean,  default: false 

Но не работает. Я попытался удалить Mongoid немного, но получить ту же ошибку:

Failure/Error: it { is_expected.to have_field(:published).of_type(Boolean).with_default_value_of(false) } Expected Post to have field named "published" of type Boolean with default value of false, got field "published" of type Mongoid::Boolean

Примечание: Я также попытался:

field :published,   type: Boolean,  default: false 

И добавили следующий метод в моей модели:

after_initialize :set_published, :if => :new_record? 

затем

private 
def set_published 
    self.published ||= false 
end 

Но ничего не работает. Что мне не хватает?

+0

Я обновил свой ответ. – vmarquet

+0

Ответ обновлен. – vmarquet

ответ

2

Если я правильно понимаю, вы пытались как Mongoid::Boolean и Boolean в модели, но не в тесте ,

Учитывая сообщение об ошибке теста, я думаю, что это должно быть:

it { is_expected.to have_field(:published).of_type(Mongoid::Boolean).with_default_value_of(false) } 

field :published, type: Mongoid::Boolean, default: false в вашей модели)

Вторая проблема:

Вы в курсе, что have_field является делать тесты на представлениях (сгенерированный HTML), а не проверять, что это поле существует в базе данных?

Мы не можем помочь вам без кода вашего мнения.

Чтобы проверить, что значение по умолчанию равно draft, я не знаю о встроенном методе Rails, поэтому вам следует сделать это вручную. Сначала создайте новый экземпляр вашей модели, сохраните его, а затем проверьте, что опубликованное поле имеет значение draft.

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

before { 
    @post = Post.new 
    # some initialization code if needed 
    @post.save 
} 
expect(@post.published).to be("draft") 
+0

Эй, @vmarquet, ваш ответ был верным, однако макс. Предложение, похоже, имело больше смысла. Спасибо за вашу помощь! – WagnerMatosUK

+0

Я не знал, нет. Мне просто нужно проверить, имеет ли модель с свойством 'опубликовано' значение по умолчанию' draft'. Как я могу это сделать? PS: Я все еще новичок с Rspec и TDD. Благодаря! – WagnerMatosUK

1
class Article 
    include Mongoid::Document 
    field :published, type: Boolean, default: false 
end 

require 'rails_helper' 

RSpec.describe Article, type: :model do 
    it { is_expected.to have_field(:published) 
         .of_type(Mongoid::Boolean) 
         .with_default_value_of(false) } 
end 

Передает прекрасно на mongoid (4.0.2), mongoid-rspec (2.1.0).

Но совершенно откровенно использование булевых элементов для состояния модели является субоптимальным.

Если вы считаете сообщение в блоге или статьи это может быть:

1. draft 
2. published 
3. deleted 
4. ... 

Добавления N числа коммутаторов в модели неприглядный - удивительное решением является использование перечислений.

Сначала написать спецификации:

RSpec.describe Article, type: :model do 

    specify 'the default status of an article should be :draft' do 
    expect(subject.status).to eq :draft 
    end 

    # or with rspec-its 
    # its(:status) { should eq :draft } 
end 

Затем добавить gem "mongoid-enum" к вашему Gemfile.

Наконец добавьте поле перечислимого:

class Article 
    include Mongoid::Document 
    include Mongoid::Enum 
    enum :status, [:draft, :published] 
end 

Перечисление добавить всю эту удивительность:

Article.published # Scope to get all published articles 
article.published? # Interrogation methods for each state. 
article.published! # sets the status 
+0

Составы-админы имеют 'it {должен define_enum_for: status}' совпадение для перечислений ActiveRecord, но я не знаю, существует ли anyring для Mongoid. – max

+0

Я вижу вашу точку зрения и изменил код на использование перечисления. Спасибо за предложение! Единственное, что я не могу найти, как проверить его на состояние по умолчанию – WagnerMatosUK

+1

Тест выше, что состояние по умолчанию - черновик. Вы также можете сделать что-то вроде 'expect (Article.new.draft?). Be_truthy', чтобы избежать использования объекта явно. – max