Rails mock_model 返回 TrueClass?

发布于 2024-09-29 12:54:43 字数 1864 浏览 5 评论 0原文

尝试在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初懵 2024-10-06 12:54:43

据我所知,在 post 语句中引用实例变量 @user 之前,您没有创建它。您最好在发布之前创建实例变量,以便先决条件立即显而易见。这样你就可以知道@user是否已设置。

我知道有些人更喜欢用一行代码更好,因为我很聪明来编写这样的东西,但我发现明确甚至重复是一个非常好的主意,特别是在测试。

我添加以下代码,我相信它可以比您所拥有的更好地表达您的意图。在我的代码中,我使用模拟期望来“期望”使用一组特定的参数创建 Project。我相信您的代码假设您可以在新创建的模拟项目和控制器执行期间创建的不同项目之间进行相等比较。这可能不是真的,因为它们是截然不同的对象。

在我的代码中,如果您对 TrueClass 等的评估有问题,您可以在示例中使用诸如 user.should be_a(User) 之类的代码来确保内容已连接正确。

def mock_user(stubs = {})
  mock_model(User, stubs)
end

def mock_project(stubs = {})
  mock_model(Project, stubs)
end

def mock_lifecycletype(stubs = {})
  mock_model(Lifecycletype, stubs)
end

it "should create project" do
  user = mock_user
  owner = user
  lifecycletype = mock_lifecycletype({ :name => "Mock Lifecycle" })

  # Not certain what your params to create are, but the argument to with
  # is what the params are expected to be
  Project.should_receive(:create).once.with({:user => user, :owner => owner, :lifecycletype => lifecycletype})

  post :create, :project => { :name => "Mock Project", 
    :description => "Mock Description",
    :owner => @user,
    :lifecycletype => lifecycletype }
  flash[:notice].should == "Project was successfully created."
end

From what I can see, you are not creating your instance variable, @user before referencing it in the post 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.

def mock_user(stubs = {})
  mock_model(User, stubs)
end

def mock_project(stubs = {})
  mock_model(Project, stubs)
end

def mock_lifecycletype(stubs = {})
  mock_model(Lifecycletype, stubs)
end

it "should create project" do
  user = mock_user
  owner = user
  lifecycletype = mock_lifecycletype({ :name => "Mock Lifecycle" })

  # Not certain what your params to create are, but the argument to with
  # is what the params are expected to be
  Project.should_receive(:create).once.with({:user => user, :owner => owner, :lifecycletype => lifecycletype})

  post :create, :project => { :name => "Mock Project", 
    :description => "Mock Description",
    :owner => @user,
    :lifecycletype => lifecycletype }
  flash[:notice].should == "Project was successfully created."
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文