康康舞规格示例
我已经为我拥有的控制器(照片)创建了一组规范,该控制器是用户的嵌套资源。 当我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对此有一个技术术语,但是测试中存在风格差异,您可以编写定义实现的测试,而我们可以编写定义结果的测试。
像这样的代码:
声明应该获取照片的方式是在照片关联上使用查找操作。由于这不是 cancan 加载照片对象的方式,因此这会导致您在测试中出现问题。
另一种方法是定义所需的结果并在测试中保留未定义的实现。这使得测试不那么脆弱,并为代码重构提供了更多机会。
这种方法的一个缺点是它需要使用工厂(
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:
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.
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.有这个答案: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.