2677


Railsで`Company`クラスが`PastData`を`has_many`で持つ関係において 下記のようなコードを書いたのですが

[code]

    describe Company do
      describe "exmaple test" do
        let(:company){ Company.create }
        context "fooが10の時" do
          let(:past_data){ company.past_data.build(foo: 10) }
          it "barは20" do
            expect(company.past_data_bar).to eq(20)
          end
        end
      end
    end
    
[/code]

### app/models/company.rb

[code]

    def past_data_bar
      past_data.bar
    end
    
[/code]

以下のように `NoMethodError`になってしまいます。

[code]

    NoMethodError:
           undefined method `bar' for nil:NilClass
    
[/code]

`company.past_data`が`nil`になっているのが原因なのはわかるのですが、解決方法がわかりませんでした。

`company.past_data.bar`と呼び出していますが、実際のコードでは`Company`クラスの内部メソッドで`past_data`を呼び出しています。

RSpecで`has_many`の関係にあるクラスを呼び出しているメソッドのテストはどのように書けば良いのでしょうか？


CC BY-SA 3.0
2014-12-27T02:45:40.477
2666
2014-12-27T06:43:09.770
2014-12-27T06:38:02.750
3271
3271
question
ruby ruby-on-rails rspec
has_manyのクラスのインスタンスをRSpecで呼び出す


company.past_dataにすると、letで宣言したオブジェクトが呼ばれないので、expectの中はpast_dataだけにしてみてください。

[code]

    describe Company do
      describe "exmaple test" do
        let(:company){ Company.create }
        context "fooが10の時" do
          let(:past_data){ company.past_data.build(foo: 10) }
          it "barは20" do
            expect(past_data.bar).to eq(20)
          end
        end
      end
    end
    
[/code]

EDIT:

コメントの内容を勘案するとこうなりそうです。

[code]

    describe Company do
      describe "exmaple test" do
        let(:company){ Company.create }
        context "fooが10の時" do
          let!(:past_data){ company.past_data.build(foo: 10) }
          it "barは20" do
            expect(past_data_bar).to eq(20)
          end
        end
      end
    end
    
[/code]

letだとbeforeやitの中でpast_dataが呼び出されるまでletのブロックは実行されません。
let!にすると、テストの実行前に必ずブロックが呼び出されるようになります。

詳しくはこの記事を読んでみてください。

[遅延評価される let と事前に実行される
let!](http://qiita.com/jnchito/items/42193d066bd61c740612#%E9%81%85%E5%BB%B6%E8%A9%95%E4%BE%A1%E3%81%95%E3%82%8C%E3%82%8B-let-%E3%81%A8%E4%BA%8B%E5%89%8D%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%82%8B-let)


CC BY-SA 3.0
2014-12-27T05:59:28.370
2677
2014-12-27T06:43:09.770
2014-12-27T06:43:09.770
85
85
2666
answer