EDIT: As per @max suggestion, I'm changing my model to use enum instead, however I can't test it for default state:
编辑:根据@max的建议,我将我的模型改为使用enum,但是我不能测试它的默认状态:
it { is_expected.to validate_inclusion_of(:status).to_allow("draft", "published") }
Works fine with the following code in the model:
在模型中可以使用以下代码:
validates :status, :inclusion => { :in => ["draft", "published"] }
But this part still fails:
但这部分仍然失败:
it { is_expected.to have_field(:status).with_default_value_of("draft") }
Please note that I'm using Mongoid. I have this in my model spec:
请注意我使用的是Mongoid。我在我的模型说明书中有:
OLD question - kept 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
Yet is not working. I've tried removing the Mongoid bit but get the same error:
但是不工作。我尝试删除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
失败/错误:{ is_expected。对于have_field(:publish).of_type(Boolean).with_default_value_of(false)}, Post希望Post的字段名称为“已发布”,类型为Boolean,默认值为false,则获取类型为Mongoid::Boolean的“已发布”字段
Note: I've also tried:
注意:我也尝试:
field :published, type: Boolean, default: false
And have added the following method in my model:
并在我的模型中增加了以下方法:
after_initialize :set_published, :if => :new_record?
then
然后
private
def set_published
self.published ||= false
end
But nothing seems to work. What am I missing?
但似乎什么都不管用。我缺少什么?
2 个解决方案
#1
2
If I understand correctly, you tried both Mongoid::Boolean
and Boolean
in your model, but not in the test.
如果我理解正确,您尝试了两个Mongoid::模型中的Boolean和Boolean,但在测试中没有。
Given the test failure 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)
(和字段:已发布,类型:Mongoid: Boolean,默认:在您的模型中为false)
Second problem:
第二个问题:
Are you aware that have_field
is to make tests on the views (the generated HTML), not to check that the field exists in the database?
您是否知道have_field用于对视图(生成的HTML)进行测试,而不是检查字段是否存在于数据库中?
We can't help you without the code of your views.
没有您的视图代码,我们无法帮助您。
To check that the default value is draft
, I'm not aware of any built-in Rails test method, so you should do it by hand. First create a new instance of your model, save it, and then check that the field published has draft
value.
要检查默认值是否为draft,我不知道任何内置的Rails测试方法,所以您应该手动执行。首先创建模型的新实例,保存它,然后检查已发布的字段是否具有draft值。
I'm not familiar with Rspec and the syntax you're using , but it should be something like (assuming you model is named Post
):
我不熟悉Rspec和您正在使用的语法,但是应该是这样的(假设您的模型名为Post):
before {
@post = Post.new
# some initialization code if needed
@post.save
}
expect(@post.published).to be("draft")
#2
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
Passes perfectly fine on mongoid (4.0.2)
, mongoid-rspec (2.1.0)
.
在mongoid(4.0.2)、mongoid-rspec(2.1.0)上传递良好。
But quite frankly using booleans for model state is sub-optimal.
但坦率地说,用布尔值表示模型状态是次优的。
If you consider a blog post or article it could be:
如果你考虑一篇博文或一篇文章,可以是:
1. draft
2. published
3. deleted
4. ...
Adding N number of switches in the model is icky - an awesome solution is to use Enums.
在模型中增加N个开关是令人讨厌的——一个很棒的解决方案是使用枚举。
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.
然后在您的Gemfile中添加gem“mongoid-enum”。
Finally add the enum field:
最后添加enum字段:
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
2
If I understand correctly, you tried both Mongoid::Boolean
and Boolean
in your model, but not in the test.
如果我理解正确,您尝试了两个Mongoid::模型中的Boolean和Boolean,但在测试中没有。
Given the test failure 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)
(和字段:已发布,类型:Mongoid: Boolean,默认:在您的模型中为false)
Second problem:
第二个问题:
Are you aware that have_field
is to make tests on the views (the generated HTML), not to check that the field exists in the database?
您是否知道have_field用于对视图(生成的HTML)进行测试,而不是检查字段是否存在于数据库中?
We can't help you without the code of your views.
没有您的视图代码,我们无法帮助您。
To check that the default value is draft
, I'm not aware of any built-in Rails test method, so you should do it by hand. First create a new instance of your model, save it, and then check that the field published has draft
value.
要检查默认值是否为draft,我不知道任何内置的Rails测试方法,所以您应该手动执行。首先创建模型的新实例,保存它,然后检查已发布的字段是否具有draft值。
I'm not familiar with Rspec and the syntax you're using , but it should be something like (assuming you model is named Post
):
我不熟悉Rspec和您正在使用的语法,但是应该是这样的(假设您的模型名为Post):
before {
@post = Post.new
# some initialization code if needed
@post.save
}
expect(@post.published).to be("draft")
#2
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
Passes perfectly fine on mongoid (4.0.2)
, mongoid-rspec (2.1.0)
.
在mongoid(4.0.2)、mongoid-rspec(2.1.0)上传递良好。
But quite frankly using booleans for model state is sub-optimal.
但坦率地说,用布尔值表示模型状态是次优的。
If you consider a blog post or article it could be:
如果你考虑一篇博文或一篇文章,可以是:
1. draft
2. published
3. deleted
4. ...
Adding N number of switches in the model is icky - an awesome solution is to use Enums.
在模型中增加N个开关是令人讨厌的——一个很棒的解决方案是使用枚举。
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.
然后在您的Gemfile中添加gem“mongoid-enum”。
Finally add the enum field:
最后添加enum字段:
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