尝试在Rspec中测试控制器。 (Rails 2.3.8,Ruby 1.8.7,Rspec 1.3.1,Rspec-Rails 1.3.3)
我正在尝试发布创建,但收到此错误消息:
登录时具有适当参数的'ProjectsController中的我的测试代码如下:
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 => "user@email.com",
:password => "password",
:password_confirmation => "password })
:owner => @current_user
注意@current_user也被模拟为用户,我测试了它(同样的方式,@current_user.class.should == User
),并在我尝试设置:owner时返回TrueClass
。
任何人都知道为什么会发生这种情况?
谢谢!
答案 0 :(得分:1)
从我所看到的情况来看,您并未在@user
语句中引用它之前创建实例变量post
。你最好在帖子之前创建实例变量,这样前提条件就会很明显。这样你就可以知道是否设置了@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