使用嵌套资源测试控制器

Testing controllers with nested resources

我是 Ruby 的新手,我正在慢慢进步。我刚开始测试。

请注意,我尚未使用任何测试框架,仅使用 rails (5.2.3) 提供的开箱即用的框架。

我的作者有很多书 has_many :books 和属于作者 belongs_to :author 的书。

这些是我的灯具:

books.yml

tmaas:
  name: The Mysterious Affair at Styles
  published: 1920
  author_id: agatha_c

tgow:
  name: The Grapes of Wrath
  published: 1939
  author_id: john_s

authors.yml

agatha_c:
  name: Agatha Christie

john_s:
  name: John Steinbeck

我运行

rails test test/controllers/books_controller_test.rb

但我在这些测试中遇到错误:

BooksControllerTest#test_should_update_book
BooksControllerTest#test_should_show_book
BooksControllerTest#test_should_get_edit
BooksControllerTest#test_should_destroy_book

错误总是一样,找不到书。

Error:
BooksControllerTest#test_should_destroy_book:
ActiveRecord::RecordNotFound: Couldn't find Book with 'id'=445166326 [WHERE "books"."author_id" = ?]
    app/controllers/books_controller.rb:72:in `set_book'
    test/controllers/books_controller_test.rb:47:in `block (2 levels) in <class:BooksControllerTest>'
    test/controllers/books_controller_test.rb:46:in `block in <class:BooksControllerTest>'

问题来自调用:

author_book_url id: books(:tmaas).id, author_id: @author.id

edit_author_book_url id: books(:tmaas).id, author_id: @author.id
test "should destroy book" do
    assert_difference('Book.count', -1) do
      delete author_book_url id: books(:tmaas).id, author_id: @author.id
    end

    assert_redirected_to author_books_url(@author)
  end

@author设置在setup

setup do
    @author = authors(:agatha_c)
  end

控制器中的set_book函数:

def set_book
      @book = @author.books.find(params[:id])
    end

我错过了什么?

这就是我的测试通过的原因:

首先,您应该将 books.yml 文件更正为:

tmaas:
  title: The Mysterious Affair at Styles
  published: 1920
  author: agatha_c

tgow:
  title: The Grapes of Wrath
  published: 1939
  author: john_s

这是我对 book_controller 操作的测试:

  1. 测试创建操作:
  test "should create book" do
    assert_difference('Book.count') do
      post author_books_url(@book.author), params: { book: { 
        author_id: @book.author_id, 
        title: @book.title,
        published: @book.published 
      }}
    end

    assert_redirected_to author_book_url(Book.last.author, Book.last)
  end
  1. 测试更新操作:
  test "should update book" do
    patch author_book_url(@book.author, @book), params: { book: { 
      author_id: @book.author_id, 
      title: @book.title,
      published: @book.published 
    } }
    assert_redirected_to author_book_url(@book.author, @book)
  end
  1. 销毁动作测试:
  test "should destroy book" do
    assert_difference('Book.count', -1) do
      delete author_book_url(@book.author, @book)
    end

    assert_redirected_to author_books_url(@book.author)
  end

查看官方Rails指南,可能会有帮助:https://guides.rubyonrails.org/testing.html#functional-tests-for-your-controllers