如何在保持 DRY 的同时测试 Common Rails 控制器行为?

发布于 2024-09-15 08:16:51 字数 519 浏览 3 评论 0原文

我一直在为一些 Rails 控制器编写 RSpec 测试,并且发现了确保 Authlogic 身份验证正常工作的强烈冲动。我还觉得我应该验证每个操作是否使用相同的应用程序范围布局。然而,在每个操作中为这种行为编写测试似乎很愚蠢。

我希望看到的是用于过滤器和布局的单行匹配器,类似于 Shoulda 的用于关联和验证的匹配器。不幸的是,似乎没有这样的匹配器可用(除了 这篇博文)。我很想自己写它们,但找不到已经写过的人,这让我怀疑是否真的需要这样的匹配器。

所以我的问题是,如何测试控制器的常见行为(如果测试的话),以及测试过滤器和布局的单行匹配器是否有用?我自己,我试图在控制器规范中的单行与显式指定过滤器相结合,或者只是指定过滤器并忽略控制器中的过滤器和布局(因为它们只是一行代码)之间做出决定。

I've been writing RSpec tests for some Rails controllers and I've discovered a strong impulse to ensure that the Authlogic authentication is working properly. I also feel like I should be verifying that each action uses the same application-wide layout. However, writing tests for this behavior in every single action seems silly.

What I'd like to see are one-line matchers for filters and layouts, similar to Shoulda's matchers for associations and verifications. Unfortunately, no such matchers seem to be available (except for some Test::Unit macros for filters in this blog post). I'm tempted to just write them myself, but not being able to find anyone who's already done it makes me question whether or not a need for such matchers actually exists.

So my question is, how do you test your controllers' common behavior (if you test it at all), and would one-liner matchers testing filters and layouts be useful? Myself, I'm trying to decide between one-liners in the controller specs combined with speccing the filter explicitly, or just speccing the filter and ignoring the filters and layouts in the controllers (since they're only one line of code anyway).

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

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

发布评论

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

评论(1

黄昏下泛黄的笔记 2024-09-22 08:16:51

我不喜欢为过滤器编写规范的想法——这似乎太接近实现了。如果您使用 TDD/BDD 方法从头开始构建控制器,那么您可能会先编写操作,添加一些逻辑(例如处理身份验证),然后意识到它应该进入过滤器。如果您的规范是“如果当前用户不是帐户用户,则拒绝索引请求”,那么您的规范应该能够执行类似(aircode)的操作:

current_user = Factory.create(:unauthorized)
controller.should_not receive(:index)
get :index
request.should redirect_to(some_safe_path)

但它不会无论操作是否使用过滤器。

您可以使用 Rspec 宏来干燥控制器规格。所以(更多的挥手)

describe MyController do
  should_reject_anonymous(self)
  ...
end

module ControllerMacros
  def should_reject_anonymous(test_controller)
    describe test_controller, "Authentication" do
      it "rejects index" do
        test_controller.should_not_receive(:index)
        get :index
        response.should redirect_to(some_safe_path)
      end
    end
  end
end

I don't like the idea of writing specs for filters -- that seems too close to the implementation. If you had used TDD/BDD methods to build your controller from scratch, presumably you'd have written the action first, added some logic (e.g. to handle authentication) and then realized it should go into a filter instead. If your spec is along the lines of "Reject an index request if the current user is not the account user", your spec ought to be able to do something like (aircode):

current_user = Factory.create(:unauthorized)
controller.should_not receive(:index)
get :index
request.should redirect_to(some_safe_path)

And it doesn't matter whether the action is using a filter or not.

You can DRY up controller specs with Rspec macros. So (more hand-waving):

describe MyController do
  should_reject_anonymous(self)
  ...
end

module ControllerMacros
  def should_reject_anonymous(test_controller)
    describe test_controller, "Authentication" do
      it "rejects index" do
        test_controller.should_not_receive(:index)
        get :index
        response.should redirect_to(some_safe_path)
      end
    end
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文