gpt4 book ai didi

ruby-on-rails - Devise 无法在使用 FactoryGirl 的 Controller 测试中正确登录

转载 作者:行者123 更新时间:2023-12-04 06:10:05 25 4
gpt4 key购买 nike

在我的 Controller 测试中尝试让 Devise 正确登录时,我遇到了一些有趣的行为。它似乎在某些情况下有效,但在其他情况下无效。我不确定这是 Devise 和 FactoryGirl 之间的互动还是其他原因。

首先,这是我的工厂:

factory :advisor do
name "Jason Jones"
association :user
initialize_with {Advisor.find_or_create_by_name('Jason Jones')}
end

factory :client do
name "Rich Homeowner"
association :advisor
end

factory :user do
email "jason@jones.com"
password "testpassword"
initialize_with {User.find_or_create_by_email('jason@jones.com')}
end

我的 Controller :

class ClientsController < ApplicationController
before_filter :authenticate_user!

def destroy
@client = current_user.advisor.clients.where(:id => params[:id]).first

@client.destroy
flash[:notice] = 'Client deleted.'
redirect_to clients_path
end

和我的 Controller 测试:

 describe "DELETE destroy" do
it "should delete a client" do

a = FactoryGirl.create(:advisor)
c = FactoryGirl.create(:client, :advisor => a)
login_user(a.user)

expect{
delete :destroy, :id => c.id
response.should be_redirect
assigns(:client).should eq(c)
}.to change(Client, :count).by(-1)

end
end

login_user 规范助手是它变得时髦的地方。如果我取消注释下面的行,强制将用户设置为 FactoryGirl 对象,则测试通过。如果我留下评论,Devise 会尝试以传递的用户身份登录(我已通过调试验证它是数据库中的同一用户),但它实际上并没有登录。在这两种情况下,sign_in 调用实际上返回相同的数组, 但基于执行路径, Controller 代码永远不会执行,因为 Devise 重定向到登录页面。

def login_user(user=nil)
@request.env["devise.mapping"] = Devise.mappings[:user]


if user.nil?
user = FactoryGirl.create(:user)
end

# user = FactoryGirl.create(:user) # uncommenting this line causes test to pass

sign_in user
end

如何让登录正常工作?

郑重声明,当涉及到 Rails 的 TDD 时,我花了 10 分钟让我的实际代码正常工作,并花了 2 小时来不断地让我的测试代码完成它应该做的事情。

最佳答案

我最近开始尝试吞下 TDD 的哲学,并承认我和你一开始的感觉完全一样。您的时间估计似乎非常准确,10 分钟的开发时间和 2 小时的测试用例实现时间。我的第一个建议是,就像生活中的许多事情一样,它会变得更好。当您第一次做出看似无害的更改然后意识到您已经打破了测试回归的一半时,您会很高兴您吃了避孕药。

话虽如此,这听起来像是在逃避,因为您在问为什么 Devise 不起作用,而我的回答是:您不应该在意。很明显你做错了什么,恐怕我无法从所提供的信息中判断它是什么,但我想我还是可以提供帮助。

我在上面看到的唯一错误是您的规范至少测试了四件事:

  1. 响应是重定向。
  2. @client 已分配。
  3. Client 被销毁。
  4. Devise 提供适当的身份验证。

规范应该测试一件事,而且只测试一件事。尽管测试更多可能很诱人,但我不推荐它。 Cucumber 或其他集成测试测试一堆东西,但不测试规范。

Devise 不是您应该在此处测试的内容,因此请将其 stub 。我认为这样的事情会起作用:

before :each do
@advisor = FactoryGirl.create(:advisor)
controller.stub(:authenticate_user!).and_return(true)
controller.stub(:current_user).and_return(@advisor.user)
end

在此之后,为您正在测试的三件事创建三个不同的它“应该”做 block 。

另一个提示是,我认为您在定义 FactoryGirl factory 时不需要指定 association。我认为这只是多态关联所需要的。通常你可以只给出没有值的关联名称,它会运行同名的工厂。请注意无限循环。

希望对您有所帮助。

关于ruby-on-rails - Devise 无法在使用 FactoryGirl 的 Controller 测试中正确登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14544212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com