【问题标题】:Why does this integration test with post request fail?为什么这个与发布请求的集成测试失败?
【发布时间】:2015-06-27 15:49:34
【问题描述】:

我为写入两个表/模型的注册表单编写了集成测试。它失败并显示消息"Organization.count" didn't change by 1。但是,是否有一种方法可以查看测试失败的错误消息类型(该表单在开发中有效,尽管显示错误消息存在问题,所以我不明白为什么测试失败)。所以我的意思是如果你在服务器上做了同样的事情来帮助我找出为什么它没有保存组织/用户,你会看到错误消息。

  test "valid combined organization user signup" do
    get new_path
    assert_template 'organizations/new'
    assert_difference ['Organization.count', 'User.count'], 1 do
      post organizations_path, organization: { name: "Abc1",
                                               bag: "aef1",
                            users_attributes: [email: "test@test.br",
                                               username: "abc1",
                                               password: "foobar",
                                               password_confirmation: "foobar"] }
       end
  end

也许测试日志可以提供帮助?我在这里看到IS NULL LIMIT 用于用户电子邮件和用户名。鉴于测试语法,我不明白为什么......

Started POST "/organizations" 
Processing by OrganizationsController#create as HTML
  Parameters: {"organization"=>{"name"=>"Abc def 1", "bag"=>"adef1", "users_attributes"=>[{"email"=>"adef1@uniqu.br", "username"=>"adef1", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}]}}
  [1m[36m (0.2ms)[0m  [1mSAVEPOINT active_record_1[0m
  [1m[35mOrganization Exists (0.6ms)[0m  SELECT  1 AS one FROM "organizations" WHERE LOWER("organizations"."name") = LOWER('Abc def 1') LIMIT 1
  [1m[36mOrganization Exists (0.3ms)[0m  [1mSELECT  1 AS one FROM "organizations" WHERE LOWER("organizations"."bag") = LOWER('adef1') LIMIT 1[0m
  [1m[35mOrganization Exists (0.3ms)[0m  SELECT  1 AS one FROM "organizations" WHERE LOWER("organizations"."name") = LOWER('Abc def 1') LIMIT 1
  [1m[36mOrganization Exists (0.3ms)[0m  [1mSELECT  1 AS one FROM "organizations" WHERE LOWER("organizations"."bag") = LOWER('adef1') LIMIT 1[0m
  [1m[35mSQL (0.4ms)[0m  INSERT INTO "organizations" ("name", "bag", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "Abc def 1"], ["bag", "adef1"], ["created_at", "2015-06-27 16:28:56.179789"], ["updated_at", "2015-06-27 16:28:56.179789"]]
  [1m[36mUser Exists (0.6ms)[0m  [1mSELECT  1 AS one FROM "users" WHERE "users"."email" IS NULL LIMIT 1[0m
  [1m[35m (0.6ms)[0m  SELECT "users"."email" FROM "users"  ORDER BY "users"."username" ASC
  [1m[36mUser Exists (0.2ms)[0m  [1mSELECT  1 AS one FROM "users" WHERE "users"."username" IS NULL LIMIT 1[0m
  [1m[35m (0.2ms)[0m  ROLLBACK TO SAVEPOINT active_record_1

控制器方法贴在这里:stackoverflow.com/q/31072646/4499505organizations_path指create方法)

如果我将测试日志与开发日志进行比较(因为在开发中表单确实有效),对于开发来说,它会在下面发布帖子,这似乎与测试日志中的帖子不同。我应该如何调整测试语法以创建与开发中相同的帖子?

Parameters: {"utf8"=>"✓", "authenticity_token"=>"***", "organization"=>{"name"=>"test60", "bag"=>"tes60", "users_attributes"=>{"0"=>{"email"=>"test60@example.com", "username"=>"test60", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}}, "commit"=>"Register"}

更新:为了匹配开发日志,我将测试中的post 行更改为:

post organizations_path, organization: { name: "Abc def 1",
                                         bag: "adef1",
             users_attributes: { "0" => {email: "adef1@uniqu.br",
                                         username: "adef1",
                                         password: "foobar",
                                         password_confirmation: "foobar"}} }
end

现在在测试日志中它不再有 IS NULL LIMIT 但它仍然回滚,因此测试仍然失败并显示相同的消息:

  [1m[35mSQL (0.5ms)[0m  INSERT INTO "organizations" ("name", "bag", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "Abc def 1"], ["bag", "adef1"], ["created_at", "2015-06-27 19:49:45.430750"], ["updated_at", "2015-06-27 19:49:45.430750"]]
  [1m[36mUser Exists (0.4ms)[0m  [1mSELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('adef1@uniqu.br') LIMIT 1[0m
  [1m[35m (0.5ms)[0m  SELECT "users"."email" FROM "users"  ORDER BY "users"."username" ASC
  [1m[36mUser Exists (0.5ms)[0m  [1mSELECT  1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('adef1') LIMIT 1[0m
  [1m[35m (0.2ms)[0m  ROLLBACK TO SAVEPOINT active_record_1

【问题讨论】:

  • 猜测错误的测试数据,但没有底层代码,这是一个猜测。为什么计数没有加一,取决于底层逻辑,这个测试不关心这个。
  • 并且没有办法看到 Rails 在尝试保存时返回的那种错误?因为现在它基本上只报告它没有保存,没有说明原因。顺便说一下,底层逻辑我在这里单独发布了一个问题:stackoverflow.com/q/31072646/4499505
  • 不在此测试中。也许是对反应的测试。我假设您对此进行了成功的单元测试?
  • 是的,我有没有问题的模型和控制器测试。我已经添加了测试日志,我认为IS NULL LIMIT 表示用户有问题。它似乎想为电子邮件和用户名保存 nil 值。不太明白为什么给出测试语法。
  • 如果它没有获取电子邮件或用户名值,那么您可能没有正确发布它们。 OrganizationUser 之间的模型关联是什么?看起来您正在发布一个有 1 个用户的组织,但参数 users_attributes 让我认为您应该发布一组用户而不是用户对象。

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


【解决方案1】:

您的测试代码与您的开发代码所做的不同。您需要在users_attributes 数组内添加括号:

test "valid combined organization user signup" do
  get new_path
  assert_template 'organizations/new'
  assert_difference ['Organization.count', 'User.count'], 1 do
    post organizations_path, 
         organization: { name: "Abc1",
                         bag: "aef1",
                         users_attributes: { "0" => { email: "test@test.br",
                                                      username: "abc1",
                                                      password: "foobar",
                                                      password_confirmation: "foobar" } } }
  end
end

这就是为什么您的日志说它正在尝试查找其email IS NULL 的用户,因为它无法正确检索email 属性,所以它只是默认为NULL 而不是@ 987654327@.


编辑: 已更新以匹配工作语法。 OP 还报告说,一旦语法被修复,User 模型出现错误,没有通过username 上的最小长度验证,他通过在测试数据中使用更长的用户名来解决这个问题。

【讨论】:

  • 谢谢 Rob,我添加了括号并再次运行测试。它以相同的消息失败。测试日志显示:Parameters: {"organization"=>{"name"=>"Abc def 1", "bag"=>"adef1", "users_attributes"=>[{"email"=>"adef1@uniqu.br", "username"=>"adef1", "fullname"=>"slidaaa", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}]}}。它仍然显示IS NULL LIMIT。我还尝试在测试中省略[],但随后收到错误消息ArgumentError: When assigning attributes, you must pass a hash as an argument
  • 对不起,我通常使用 Capybara 进行集成测试,正是为了避免这些问题。我查看了您发布的工作开发参数,似乎它需要哈希中的哈希,所以您可以尝试用波浪形大括号替换方括号,然后将 "0" => 放在内部哈希之前以便匹配?
  • 谢谢,我按照描述进行了更改。尽管IS NULL LIMIT 消失了,但它仍然失败并显示相同的消息。我将它添加到 OP 中。
  • 太好了,找到了:用户名也不符合验证:最少字符数。唯一我不明白的是"0" => 的来源/它的含义。
  • 我无法解释那个,除了他们似乎在复制一个带有哈希的数组。我不知道他们为什么会那样做,但这就是它的样子。如果您考虑一下,在 Ruby 中,数组基本上是一个哈希,其约束条件是所有键都必须是按顺序排列的整数。您在散列中只有一个元素,因此它获得“第零个”索引,或者在本例中为键。如果您在表单中创建多个嵌套的User 模型,这将派上用场,并且我假设以下User 将被分配1 的键。
猜你喜欢
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多