Rails mock_model 返回 TrueClass?
尝试在 Rspec 中测试控制器。 (Rails 2.3.8、Ruby 1.8.7、Rspec 1.3.1、Rspec-Rails 1.3.3)
我正在尝试发布创建,但收到此错误消息:
ActiveRecord::AssociationTypeMismatch in 'ProjectsController withproperties whilelogging在:应该创建项目' User(#2171994580) 预期,得到 TrueClass(#2148251900)
我的测试代码如下:
def mock_user(stubs = {})
@user = mock_model(User, stubs)
end
def mock_project(stubs = {})
@project = mock_model(Project, stubs)
end
def mock_lifecycletype(stubs = {})
@lifecycletype = mock_model(Lifecycletype, stubs)
end
it "should create project" do
post :create, :project => { :name => "Mock Project",
:description => "Mock Description",
:owner => @user,
:lifecycletype => mock_lifecycletype({ :name => "Mock Lifecycle" }) }
assigns[:project].should == mock_project({ :name => "Mock Project",
:description => "Mock Description",
:owner => mock_user,
:lifecycletype => mock_lifecycletype({ :name => "Mock Lifecycle" })})
flash[:notice].should == "Project was successfully created."
end
当我尝试执行 :owner => 时,麻烦就来了上面代码中的@user
。由于某种原因,它认为我的 @user 是 TrueClass 而不是 User 类对象。有趣的是,如果我注释掉 post :create
代码,然后执行一个简单的 @user.class.should == User
,它就会起作用,这意味着 @user确实是一个 User
类对象。
我也尝试过
:owner => mock_user
:owner => mock_user({ :name => "User",
:email => "[email protected]",
:password => "password",
:password_confirmation => "password })
:owner => @current_user
注意 @current_user 也被模拟为用户,我对此进行了测试(同样的方式,@current_user.class.should == User
)并且还返回一个 TrueClass< /code> 当我尝试设置 :owner.
有人知道为什么会发生这种情况吗?
谢谢你!
Trying to test a controller in Rspec. (Rails 2.3.8, Ruby 1.8.7, Rspec 1.3.1, Rspec-Rails 1.3.3)
I'm trying to post a create but I get this error message:
ActiveRecord::AssociationTypeMismatch in 'ProjectsController with appropriate parameters while logged in: should create project'
User(#2171994580) expected, got TrueClass(#2148251900)
My test code is as follows:
def mock_user(stubs = {})
@user = mock_model(User, stubs)
end
def mock_project(stubs = {})
@project = mock_model(Project, stubs)
end
def mock_lifecycletype(stubs = {})
@lifecycletype = mock_model(Lifecycletype, stubs)
end
it "should create project" do
post :create, :project => { :name => "Mock Project",
:description => "Mock Description",
:owner => @user,
:lifecycletype => mock_lifecycletype({ :name => "Mock Lifecycle" }) }
assigns[:project].should == mock_project({ :name => "Mock Project",
:description => "Mock Description",
:owner => mock_user,
:lifecycletype => mock_lifecycletype({ :name => "Mock Lifecycle" })})
flash[:notice].should == "Project was successfully created."
end
The trouble comes when I try to do :owner => @user
in the code above. For some reason, it thinks that my @user is TrueClass
instead of a User
class object. Funny thing is, if I comment out the post :create
code, and I do a simple @user.class.should == User
, it works, meaning that @user is indeed a User
class object.
I've also tried
:owner => mock_user
:owner => mock_user({ :name => "User",
:email => "[email protected]",
:password => "password",
:password_confirmation => "password })
:owner => @current_user
Note @current_user is also mocked out as a user, which I tested (the same way, @current_user.class.should == User
) and also returns a TrueClass
when I try to set :owner.
Anybody have any clue why this is happening?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
据我所知,在
post
语句中引用实例变量@user
之前,您没有创建它。您最好在发布之前创建实例变量,以便先决条件立即显而易见。这样你就可以知道@user
是否已设置。我知道有些人更喜欢用一行代码更好,因为我很聪明来编写这样的东西,但我发现明确甚至重复是一个非常好的主意,特别是在测试。
我添加以下代码,我相信它可以比您所拥有的更好地表达您的意图。在我的代码中,我使用模拟期望来“期望”使用一组特定的参数创建
Project
。我相信您的代码假设您可以在新创建的模拟项目和控制器执行期间创建的不同项目之间进行相等比较。这可能不是真的,因为它们是截然不同的对象。在我的代码中,如果您对 TrueClass 等的评估有问题,您可以在示例中使用诸如
user.should be_a(User)
之类的代码来确保内容已连接正确。From what I can see, you are not creating your instance variable,
@user
before referencing it in thepost
statement. You would do well to create the instance variables prior to the post so the preconditions are immediately obvious. That way you could know whether@user
had been set.I know some people prefer the one-line-of-code-is-better-because-i'm-smart method of writing stuff like this, but I've found being explicit and even repetitive is a really good idea, particularly in tests.
I'm adding the following code that I believe may express your intent better that what you have. In my code, I use mock expectations to "expect" a
Project
is created with a particular set of parameters. I believe your code assumes that you can do an equality comparison between a newly-created mock Project and a different one created during execution of your controller. That may not be true because they are distinctly different objects.In my code, if you have a problem with something evaluating to TrueClass or the like, you can use a line of code like
user.should be_a(User)
to the example to make sure stuff is wired up correctly.