1

Minitest で少し遊んでみたところ、説明が見つからないように見える動作が見つかりました。

次のような非常に単純なモデル テスト ファイルがあります。

require 'minitest_helper'

describe User do

  before do
    @user = User.new(name: "Example User", email: "user@example.com",
                     password: "foobards", password_confirmation: "foobards")
  end

  describe "with admin attribute set to 'true'" do
    before { @user.toggle!(:admin) }

    it { @user.admin.must_equal true }
  end 
end

「rake db:test:prepare」の後に初めてこのコードを実行すると、テストに合格します

2 回連続して実行すると、エラーが発生します。

test_0001_anonymous 0:00:00.132
ERROR SQLite3::ConstraintException: 列の電子メールが一意ではありません: INSERT INTO "users" ("admin", "created_at", "email", "name", "password_digest", "updated_at") VALUES ( ?, ?, ?, ?, ?, ?)

それでも、このエラーは発生しないようです

before { @user.toggle!(:admin) }

私の minitest_helper.rb は次のとおりです。

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "minitest/autorun"
require "capybara/rails"
require "active_support/testing/setup_and_teardown"

class IntegrationTest < MiniTest::Spec
  include Rails.application.routes.url_helpers
  include Capybara::DSL
  register_spec_type(/integration$/, self)
end

class HelperTest < MiniTest::Spec
  include ActiveSupport::Testing::SetupAndTeardown
  include ActionView::TestCase::Behavior
  register_spec_type(/Helper$/, self)
end

Turn.config.format = :outline

これがバグなのか、それとも (より可能性が高い) 何かが足りないのか、私には理解できないようです。私より詳しい方、説明していただけないでしょうか?

4

2 に答える 2

1

toggle!メソッドはレコードを保存します。したがって、テストを 2 回目に実行すると、データベースには "user@example.com" という電子メールのレコードが既に 1 つ存在します。また、電子メール アドレスの一意性を保証する検証が失敗します。

toggle代わりに(強打なしで)使用してみてください。

于 2012-06-02T18:33:27.687 に答える
1

各テストをトランザクションでラップする (変更が保存されないようにロールバックする) か、テスト間ですべてのテーブルをクリアする必要があります。データベースからジャンクが残っていない場合、後続のテスト実行が妨げられます

database_cleaner gem はこれを行う 1 つの方法であり、さまざまな ORM に対して複数の戦略 (トランザクション、切り捨てなど) をサポートします。

于 2012-06-02T19:06:42.853 に答える