Ruby on rails 了解RSpec和Rails测试环境
可能是一个简单的答案,是模仿或存根相关的,但我是新手,试图更好地理解事物。。。我试图理解为什么测试资源实际上没有被删除?但是规格通过了,就好像它们通过了一样?这可能是RSpec独有的,也可能不是 我有一个使用RSpec的新项目,并为一个简单的资源生成了一个脚手架Ruby on rails 了解RSpec和Rails测试环境,ruby-on-rails,testing,rspec,Ruby On Rails,Testing,Rspec,可能是一个简单的答案,是模仿或存根相关的,但我是新手,试图更好地理解事物。。。我试图理解为什么测试资源实际上没有被删除?但是规格通过了,就好像它们通过了一样?这可能是RSpec独有的,也可能不是 我有一个使用RSpec的新项目,并为一个简单的资源生成了一个脚手架 $ rails new destroyer -T ... $ rails generate rspec:install ... $ rails g scaffold resource name:string 一切正常,规格通过。但我在
$ rails new destroyer -T
...
$ rails generate rspec:install
...
$ rails g scaffold resource name:string
一切正常,规格通过。但我在另一个项目中遇到了一些奇怪的事情,测试失败了,所以我在destroy方法中添加了一些日志记录,以了解发生了什么:
#app/controllers/resources_controller.rb
def destroy
@resource = Resource.find(params[:id])
@resource.destroy
logger.info "Resource Destroyed: #{@resource.destroyed?}" # <-- added
logger.info "Persisted after destroy: #{@resource.persisted?}" # <-- added
respond_to do |format|
format.html { redirect_to(resources_url) }
format.xml { head :ok }
end
end
销毁资源时,我会在日志中注意到这种差异:
development.log:
运行规范后,我在test.log中看到了以下内容:
为什么我们看到不同的国家被摧毁?取决于我们运行的环境的资源的类型?我不确定,但似乎合乎逻辑的是,因为每个示例都在事务中独立运行,所以在提交事务之前,资源不会被标记为已销毁。如果您在Cucumber场景中运行相同的东西,您可能会观察到与在development.log中看到的相同的结果。如果您使用生成的控制器规格,您将看到类似于销毁操作的内容:
require 'spec_helper'
describe PostsController do
def mock_post(stubs={})
@mock_post ||= mock_model(Post, stubs).as_null_object
end
it "destroys the requested post" do
Post.stub(:find).with("37") { mock_post }
mock_post.should_receive(:destroy)
delete :destroy, :id => "37"
end
end
规范并没有实例化一个真正的Post对象,而是使用mock_模型来创建一个mock或“test double”。为了更容易测试模型,使用mock_model创建的mock去掉了一些ActiveRecord方法,包括destrocted?并且坚持?。因此,这些模拟的行为方式与真实模型实例的行为方式不完全相同
Processing by ResourcesController#destroy as HTML
Parameters: {"id"=>"1"}
Resource Destroyed: false # <<<< ###### FALSE ######
Persisted after destroy: false
Redirected to http://test.host/resources
Completed 302 Found in 4ms
require 'spec_helper'
describe PostsController do
def mock_post(stubs={})
@mock_post ||= mock_model(Post, stubs).as_null_object
end
it "destroys the requested post" do
Post.stub(:find).with("37") { mock_post }
mock_post.should_receive(:destroy)
delete :destroy, :id => "37"
end
end