RSpecで役に立ちそうないくつかのヒント(翻訳)

概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: A Few RSpec Helpful Hints 公開日: 2017/07/12 著者: Jake Yesbeck RSpecで役に立ちそうないくつかのヒント(翻訳) Rubyのテスティングにおける二大勢力といえば、RSpecとMiniTestです。RSpecは(訳注: 英語的に)非常に表現力の豊かなテスティングフレームワークであり、テストを読みやすくする素晴らしい機能やヘルパーが多数用意されています。ここでは、RSpecのテストを書きやすく、読みやすく、メンテしやすくするのに役立つ、あまり知られていないテクニックをご紹介いたします。 以下は、BooksとAuthorsがあるシステムのコードです。読みやすいテストコードを書いてみましょう。 class Book attr_reader :title, :genre def initialize(title, genre) @title = title @genre = genre end end class Author attr_reader :books def initialize(name, books) @name = name @books = Array(books) end def has_written_a_book? !books.empty? end end subject変数とlet変数 subject変数やlet変数の宣言は、specの繰り返しを避けてDRYに書くよい方法のひとつです。 subject変数やlet変数を使わないと、たとえば「Authorにnameがあること」というアサーションは次のようになってしまうでしょう。 describe Author do before do @book_genre = ‘歴史創作もの’ @book_title = ‘二都物語’ @book = Book.new(@book_genre, @book_title) @author_name = ‘チャールズ・ディケンズ’ @author = Author.new(@author_name, [@book]) end describe ‘#name’ do it ‘nameが1つある’ do expect(@author.name).to eq(@author_name) end end end これは正しいのですが、本の冊数やペンネームといったテスト項目を追加するうちにAuthorのテストが繰り返しだらけになってしまいます。 以下のようにsubject変数やlet変数を使えば、コードがDRYになり、再利用しやすくなります。 describe Author do let(:book_genre) { ‘歴史創作もの’ } #👈 let(:book_title) { ‘二都物語’ } #👈 let(:book) { Book.new(book_genre, book_title) } #👈 let(:book_array) { [book] } #👈 let(:author_name) { ‘チャールズ・ディケンズ’ } #👈 subject { Author.new(author_name, book_array) } #👈 describe ‘#name’do it ‘nameが1つある’ do expect(subject.name).to eq(author_name) end end describe ‘#books’ do context ‘with books’ do it ‘著書が1つ以上ある’ do expect(subject.books).to eq(book_array) end end context ‘著書がない場合’ do context ‘books変数がnil’ do let(:book_array) { nil } #👈 it ‘booksは空の配列になる’ do expect(subject.books).to eq([]) end end context ‘books変数が空の配列の場合’ do let(:book_array) { [] } #👈 it ‘booksは空の配列になる’ do expect(subject.books).to eq([]) … Continue reading RSpecで役に立ちそうないくつかのヒント(翻訳)