How to get a BOM test case for a model with an enum field type - Mongoid

EDIT: As suggested by @max, I change my model to use an enum, but cannot check it for the default state:

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

      

Works well with the following code in the model:

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

      

But this part still doesn't work:

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

      

Please note that I am using Mongoid. I have this in my model spec:

OLD question - saved for reference?

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

      

And in my model I have this:

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

      

Doesn't work yet. I tried to remove the Mongoid bit but got the same error:

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

Note. I've also tried:

field :published,         type: Boolean,     default: false

      

And added the following method to my model:

after_initialize :set_published, :if => :new_record?

      

then

private
def set_published
  self.published ||= false
end

      

But nothing works. What am I missing?

+3


source to share


2 answers


If I understand correctly, you have tried both Mongoid::Boolean

, and Boolean

in the model, but not in the test.

Given the testing error message, I think it should be:

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

      

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

in your model)

Second problem :



Do you know what have_field

tests on views (generated HTML) are supposed to do and not check if this field exists in the database?

We cannot help you without your views code.

To check what the default is draft

, I am not aware of the built-in Rails method, so you have to do it manually. First create a new instance of your model, save it, and then make sure the published field has a value draft

.

I'm not familiar with Rspec and the syntax you are using, but it should be something like (if your model is called Post

):

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

      

+2


source


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

      

It runs fine on mongoid (4.0.2)

, mongoid-rspec (2.1.0)

.

But quite frankly, using boolean states for model state is sub-optimal.

If you are considering a blog post or article, it could be:

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

      

Adding N number of switches to the model is icky - an awesome solution is using Enums.

First write the spec:



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

      

Then add gem "mongoid-enum"

to your Gemfile.

Finally, add an enum field:

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

      

Enums add all this awesomeness:

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

      

+1


source







All Articles