如何使用 Rails miniTest 创建新书并指定两位作者?

How can I create new book and assign two authors with it using Rails miniTest?

进行 TDD

我在创建一本书并将其分配给两位作者时遇到了问题。创作失败。它说有一个 AssociationTypeMismatch: Author(#15100) expected, got nil 它是 NilClass(#40) 的一个实例。我想格式“作者:[]”没有被某些东西很好地阅读。

这是测试:

def test_has_many_and_belongs_to_mapping
 apress = Publisher.find_by(name: 'Apress')
 assert_equal 2, apress.books.size

 book = Book.new(
  title: 'Rails E-Commerce 3nd Edition',
  authors: [
    Author.find_by(first_name: 'Christian', last_name: 'Hellsten'),
    Author.find_by(first_name: 'Jarkko', last_name: 'Laine')
  ],
  published_at: Time.now,
  isbn: '123-123-123-x',
  blurb: 'E-Commerce on Rails',
  page_count: 300,
  price: 30.5
 )

 # apress.books << book

 # apress.reload
 # book.reload

 # assert_equal 3, apress.books.size
 # assert_equal 'Apress', book.publisher.name
end

这是错误:

我的 ERD:

我的架构:

我认为您缺少的是在此测试运行之前需要的有意义的 setup 数据。即使这些出版商和书籍可能存在于您的开发中 environment/database,测试套件通常配置为在运行之间清除数据库。

如果您定义了灯具,那么您可以像这样引用它们:

test/fixtures/publishers.yml

apress:
  id: 1
  name: Apress

test/fixtures/authors.yml

hellsten:
  id: 1
  first_name: Christian
  last_name: Hellsten

laine:
  id: 2
  first_name: Jarkko
  last_name: Laine

test/fixtures/books.yml

beginning_ruby:
  title: Beginning Ruby
  publisher_id: 1

ruby_recipes:
  title: Ruby Recipes
  publisher_id: 1

这样测试看起来更像这样:

def test_has_many_and_belongs_to_mapping
 apress = publishers(:apress)
 assert_equal 2, apress.books.size

 book = Book.new(
  title: 'Rails E-Commerce 3nd Edition',
  authors: [
    Author.find_by(first_name: 'Christian', last_name: 'Hellsten'),
    Author.find_by(first_name: 'Jarkko', last_name: 'Laine')
  ],
  published_at: Time.now,
  isbn: '123-123-123-x',
  blurb: 'E-Commerce on Rails',
  page_count: 300,
  price: 30.5
 )

 apress.books << book

 apress.reload
 book.reload

 assert_equal 3, apress.books.size
 assert_equal 'Apress', book.publisher.name
end

或者不使用固定装置,您可以在测试前创建内容:

这样测试看起来更像这样:

setup do
  publisher = Publisher.create!(name: 'Apress')
  publisher.books.create!(title: 'Beginning Ruby')
  publisher.books.create!(title: 'Ruby Recipes')
  Author.create!(first_name: 'Christian', last_name: 'Hellsten')
  Author.create!(first_name: 'Jarkko', last_name: 'Laine')
end

def test_has_many_and_belongs_to_mapping
 apress = Publisher.find_by(name: 'Apress')
 assert_equal 2, apress.books.size

 book = Book.new(
  title: 'Rails E-Commerce 3nd Edition',
  authors: [
    Author.find_by(first_name: 'Christian', last_name: 'Hellsten'),
    Author.find_by(first_name: 'Jarkko', last_name: 'Laine')
  ],
  published_at: Time.now,
  isbn: '123-123-123-x',
  blurb: 'E-Commerce on Rails',
  page_count: 300,
  price: 30.5
 )

 apress.books << book

 apress.reload
 book.reload

 assert_equal 3, apress.books.size
 assert_equal 'Apress', book.publisher.name
end

这样你的数据库就有这些值,你的 find_by() 调用应该 return 数据,而不是 nil