【问题标题】:Rails API new user not created in testRails API 新用户未在测试中创建
【发布时间】:2020-07-24 23:05:08
【问题描述】:

我正在使用 API 端点来注册新用户。我可以使用 cURL 在本地添加用户: curl -X POST -d email="usrname@example.com" -d password="APassword!" http://localhost:3000/api/v1/registrations/,将成功添加用户。

但是如果我为端点写一个测试:

  test 'Should register a new user' do

      user_params = { user: {
    email: Faker::Internet.email,
    password: Faker::Internet.password
  } }

    post '/api/v1/registrations', params: user_params
                                  headers: { 'Content-Type': 'application/json' }
    user = User.find_by(email: user_params[:user][:email])
    assert_not_nil user
  end

这将失败,用户将为零:Expected nil to be truthy.

我读到的一件事是,使用 Rails,如果在路由或控制器中正确定义了标题类型 application/json,则不必在请求中指定它。这似乎是因为我没有将标头传递给 cURL 请求。我尝试从测试中删除 headers:

  post '/api/v1/registrations', params: user_params.to_json

但我有同样的问题,测试结果还是一样。

实际的 registrations_controller.rb 如下所示:


  def create
    @user = User.new(sign_up_params)

    if @user.save
      render json: @user
    else
      render json: { errors: @user.errors }
    end
  end

  private

  def sign_up_params
    params.permit(:email, :password, :password_confirmation)
  end

【问题讨论】:

  • 你可以试试post '/api/v1/registrations', params: user_params
  • 我遇到了同样的问题并且测试失败了。
  • 通常我们通过expect(response).to be_successful来测试用户是否创建成功。并且您还想使用电子邮件进行测试,您应该检查收到的回复,您是否在创建记录时返回电子邮件?然后你可以检查expect(json).to be_kind_of Hash expect(json['email']).to eq(params[:user][:email]) 至于你的场景你应该把user对象看看你运行时得到什么这个查询。
  • 您不需要手动将参数编码为 JSON - 只需传递一个哈希 -params: user_params 这可能会导致双重编码问题。一般来说,在 Rails 中,如果你曾经在一个对象上调用 .to_json,你可能做错了。此外,由于您将 user_params 声明为该范围内的局部变量,因此不会为每个示例生成唯一值。您想使用之前/设置块/方法或记忆值的方法,如 RSpecs let
  • @KamalPanhwar 用户对象由注册控制器中的create 方法返回:render json: @user。我做了一个response.body 来看看什么回来了,我得到了:{"errors":{"email":["can't be blank"],"password":["can't be blank","Passwords must be at least 8 caracters long"]}}, response 我仔细检查了user_params,这是传入的内容:{:user=>{:email=>"delbert@christiansen.com", :password=>"1ItNuTgMhSqCs0"}}

标签: ruby-on-rails ruby-on-rails-6 rails-api


【解决方案1】:

问题出在 user_params 中。 sign_up_params 期待电子邮件和密码,而不是用户对象(我用来嵌套电子邮件和密码)。此外,还需要密码确认。

  def sign_up_params
    params.permit(:email, :password, :password_confirmation)
  end

因此将 user_params 更改为:

    pass = Faker::Internet.password
    user_params = {
      email: Faker::Internet.email,
      password: pass,
      password_confirmation: pass
    }

已经奏效了,我认为其他人的好建议(例如从 params 哈希中删除 to_json 方法)也让我顺利通过了这一点。

我不知道是否应该将我的 API 调用包装在 user 对象中,我以前从未构建过 API。我只是想反映我在其他 Rails 项目中所做的事情,但添加了 JWT 和 API 特定端点。

【讨论】:

  • 这是你的选择,有些人喜欢发送包裹在 user: {} 中的 json 请求,而有些人只是发送 {email: '' ...} 所以这是你的选择和前端人员的要求。但在标准中,我认为他们更喜欢 user: { ....} 风格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 2021-05-23
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多