如何改变测试

时间:2015-04-21 22:15:05

标签: ruby-on-rails ruby ruby-on-rails-4 testing

在测试文件中,我有一个功能行:

get edit_password_reset_path(member.reset_token, email: "")

在控制器中我有:

def edit
end

这有效,但现在我必须将控制器更改为:

  def edit
    if @organization
      render action: "editorg"
    elsif @member
      render action: "editmem"
    end
  end

根据用户的类型,这允许以不同的形式显示密码重置。所以有一个editorg.html.erb和一个editmem.html.erb。这又有效。

旧的测试线无效。但是,由于测试线引用的路径路径没有改变,我应该如何更改?实际上,它仍然在查找edit.html.erb,我收到错误消息:ActionView::MissingTemplate: Missing template password_resets/edit ...

如果需要有关测试文件的更多信息:

  def setup
    ActionMailer::Base.deliveries.clear
    @member = members(:michael)
  end

  test "password resets" do
    get new_password_reset_path
    assert_template 'password_resets/new'
    # Invalid email
    post password_resets_path, password_reset: { email: "" }
    assert_not flash.empty?
    assert_template 'password_resets/new'
    # Valid email
    post password_resets_path, password_reset: { email: @member.email }
    assert_not_equal @member.reset_digest, @member.reload.reset_digest
    assert_equal 1, ActionMailer::Base.deliveries.size
    assert_not flash.empty?
    assert_redirected_to root_url
    # Password reset form
    member = assigns(:member)
    # Wrong email
    get edit_password_reset_path(member.reset_token, email: "")
    ...here I get the error message.

控制器中填充@organization@member的逻辑如下所示。我表明它在两个表中查找用户(它将在这两个表之一中找到用户)。

before_action :get_user, only: [:edit, :update]
    def get_user
      @member = Member.find_by(email: params[:email])
      @organization = Organization.find_by(email: params[:email])
    end

2 个答案:

答案 0 :(得分:0)

问题是@member@organization的查找逻辑都依赖于设置params[:email]

@member = Member.find_by(email: params[:email])
@organization = Organization.find_by(email: params[:email])

但是你传递的是email

get edit_password_reset_path(member.reset_token, email: "")

您需要为测试数据库中存在的组织和成员传递有效的电子邮件。您可能需要在测试设置期间使用夹具,工厂或普通的旧ActiveRecord创建记录。

答案 1 :(得分:0)

我会发布这个作为答案,以提供更多空间,虽然它不是一个完整的解决方案。

如果您查看您正在执行的测试代码:

get edit_password_reset_path(member.reset_token, email: "")

即。没有电子邮件地址的请求。这可能是您想要的,因为密码重置请求应该使用重置令牌。但是,在您的get_user中,您只能通过电子邮件查询执行查找,以便无法正常工作。

您可能希望将其更改为

if params[:email].present?
  # find by mem/org by email
else
  # try finding by reset token
end

你提到这在开发中是有效的,所以看看在开发中传递的URL和参数,并查看你的路由或参数,看看param包含重置令牌的位置,这样你就可以在你的根据需要查找查询。

无论如何,请注意,不要使用只使用电子邮件地址更改密码且无需正确重置令牌的解决方案。