康康舞规格示例

发布于 2024-11-03 11:11:33 字数 1698 浏览 4 评论 0原文

我已经为我拥有的控制器(照片)创建了一组规范,该控制器是用户的嵌套资源。 当我在 Photos 控制器中引入 CanCan 时,规范全部通过,但其中一些规范失败:

load_and_authorize_resource :user
load_and_authorize_resource :photo

这是我的规范之一中的一个失败的测试用例:

describe "get 'show'" do
   let(:photo) { Factory.stub(:photo) }
   it "searches for the users photo" do 
      @user.photos.should_receive(:find).with(:photo.object_id); 
      get :show, :user_id => @user.id, :id => :photo.object_id; 
   end
   context "when the photo doesn't exist" do
      before do 
         @user.photos.stub(:find).with(:photo.object_id).and_raise(ActiveRecord::RecordNotFound); 
         get :show, :user_id => @user.id, :id => :photo.object_id;  
      end
      it "assigns photo to nil" do 
         assigns[:photo].should be_nil;  
      end
      it "renders the '404' template" do 
         response.status.should eql 404; 
         response.should render_template("#{Rails.root.to_s}/public/404.html") end
      end
   end
   ...
 end

我已在规范文件的顶部设置了用户:

login(:user)

before do
   @user = controller.current_user # this could be any user.
   User.stub!(:find).and_return(@user)
end

以及照片控制器如下所示:

def show
  # @user = User.find(params[:user_id])
  # @photo = @user.photos.find(params[:id])
end

请注意,该操作为空,因为 Cancan 会自动执行所需的查找。在介绍康康舞之前,动作中的两行台词没有被注释掉。

例如,在我的测试中,当我测试在用户照片上调用 find 方法时,测试失败。 Cancan 必须使用其他技术来查找用户照片(@users.photos.find() 除外)。有人知道如何为使用 Cancan 的控制器重写上述测试,即用可以工作的东西替换查找存根吗?

我正在寻找的理想情况是使用 Cancan 的 RESTful 控制器的一些示例规范。即使是显示操作的规范也会很有用。

感谢您的阅读!
Eddie

ps - 我正在使用 Rails 3.0.6、Cancan 1.6.4 和 Devise 1.3.3

I've created a sets of specs for a controller that I have (Photo) that is a nested resource of a User.
The specs all pass but some of them fail when I introduce CanCan in the Photos contoller:

load_and_authorize_resource :user
load_and_authorize_resource :photo

Here's a failing test case from one of my specs:

describe "get 'show'" do
   let(:photo) { Factory.stub(:photo) }
   it "searches for the users photo" do 
      @user.photos.should_receive(:find).with(:photo.object_id); 
      get :show, :user_id => @user.id, :id => :photo.object_id; 
   end
   context "when the photo doesn't exist" do
      before do 
         @user.photos.stub(:find).with(:photo.object_id).and_raise(ActiveRecord::RecordNotFound); 
         get :show, :user_id => @user.id, :id => :photo.object_id;  
      end
      it "assigns photo to nil" do 
         assigns[:photo].should be_nil;  
      end
      it "renders the '404' template" do 
         response.status.should eql 404; 
         response.should render_template("#{Rails.root.to_s}/public/404.html") end
      end
   end
   ...
 end

I've set up the user at the top of the spec file:

login(:user)

before do
   @user = controller.current_user # this could be any user.
   User.stub!(:find).and_return(@user)
end

and the show method in the Photos controller looks like this:

def show
  # @user = User.find(params[:user_id])
  # @photo = @user.photos.find(params[:id])
end

Note that the action is blank because Cancan performs the finds required automatically. Before I introduced Cancan the two lines in the action weren't commented out.

In my test, when I test that the find method is called on a users photos for example, the test fails. Cancan must be using some other technique to find the users photos (other than @users.photos.find()). Would anyone know how to rewrite the above tests for a controller that users Cancan, i.e. to replace the find stubs with something that will work?

What I'm looking for ideally is some sample specs for a RESTful controller that uses Cancan. Even a spec for the show action would be useful.

Thanks for reading!
Eddie

ps - I'm using Rails 3.0.6, Cancan 1.6.4 and Devise 1.3.3

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

半山落雨半山空 2024-11-10 11:11:33

对此有一个技术术语,但是测试中存在风格差异,您可以编写定义实现的测试,而我们可以编写定义结果的测试。

像这样的代码:

@user.photos.should_receive(:find).with(:photo.object_id); 

声明应该获取照片的方式是在照片关联上使用查找操作。由于这不是 cancan 加载照片对象的方式,因此这会导致您在测试中出现问题。

另一种方法是定义所需的结果并在测试中保留未定义的实现。这使得测试不那么脆弱,并为代码重构提供了更多机会。

assigns[:photo].should eq photo;

这种方法的一个缺点是它需要使用工厂(Factory.create)而不是夹具(Factory.stub),但在我看来,更灵活的测试风格证明是合理的它。

There's a technical term for this, but there's a style difference in testing where you can either write a test which defines the implementation, our a test that defines the result.

Code like this:

@user.photos.should_receive(:find).with(:photo.object_id); 

Declares that the way that the photo should be fetched is using a find operation on the photos association. As this is not the way that cancan loads the photo object, this is causing you problems in your tests.

An alternative approach is to define the desired outcome and leave the implementation undefined in the test. This makes the tests less brittle, and opens up more opportunities for code refactoring.

assigns[:photo].should eq photo;

A downside of this approach is it requires the use of Factories (Factory.create) instead of Fixtures (Factory.stub), but in my opinion the more flexible testing style justifies it.

弥繁 2024-11-10 11:11:33

有这个答案:Rspec、CanCan 和 Devise,但我不太确定我想要补丁CanCan。我更愿意以正确的方式理解和规范模拟。我知道关键问题是 CanCan 不调用 Contact.new(params[:contact])。相反,它会在根据当前能力权限应用一些初始属性后调用 contact.attributes = params[:contact] 。如何解决这个问题?这就是我现在所做的工作。

there is this answer: Rspec, CanCan and Devise, but i am not really sure I want to patch CanCan. I would much rather understand and spec out the mock in the right way. I know the key issue is that CanCan does not call Contact.new(params[:contact]). Instead it calls contact.attributes = params[:contact] later after it has applied some initial attributes based on the current ability permissions. How to work around that? That is what I'm working now.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文