

### model

[code]

    class Test
    　　def initialize (val1, val2)
    　　　　validate(val1, val2)
    　　end
    　　private 
    　　def validate(val1, val2)
    　　　　raise xxxxerror unless val1.presnet?
    　　　　raise yyyyerror unless val2.presnet?
    　　end
    end
    
[/code]

### validateのテストを行いたい

一般的な書き方

[code]

    @test = Test.new(val1, val2)
    @test.send(:validate, val1, val2)
    
[/code]

→validateが2回走る？（インスタンス生成時とsendで実行した時

解決方法  
①newをstubしてTestクラスのダミーインスタンスを返却？  
（ダミーインスタンスの方法がわからないです。。。）

②他の方法でprivateメソッドを直接呼び出す  
（呼び出す方法が分からないです。。。）

### 聞きたいこと

①、②どちらが良いのか  
①の場合どうやってダミーインスタンスを返却するのか  
②の場合、具体的にどんな書き方で呼び出すのか  
を知りたいです。

spec始めたばかりの初心者で申し訳ないですがご教示いただけると嬉しいです。


CC BY-SA 3.0
2017-04-24T11:47:23.940
34243
2017-06-07T01:33:12.183
2017-04-24T13:17:04.950
76
22759
question
ruby rspec テスト
モデルのプライベートメソッドのテスト方法


基本的にprivateメソッドのテストはしないと思います。

この場合でしたら `Test#initialize`(これもprivateメソッドなので実際には `Test.new`)
のテストをするほうがよいのではないでしょうか。

[code]

    expect { Test.new(...) }.to raise_error(xxxerror)
    
[/code]


CC BY-SA 3.0
2017-04-24T13:51:38.220
34244
2017-04-24T13:51:38.220
17037
34243
answer


initializeメソッドを実行せずにオブジェクトだけ確保するには[`Class#allocate`](https://docs.ruby-
lang.org/ja/latest/method/Class/i/allocate.html)でできます。

[code]

    @test = Test.allocate
    @test.send(:validate, val1, val2)
    
[/code]

rspecでしたら

[code]

    expect { Test.allocate.send(:validate, val1, val2) }.to raise_error XXXXError
    
[/code]

ただし、継承元クラスがあればそれのinitializeも実行されず、本当に中身のないオブジェクトになるのでテストコードが煩雑になりかねません。  
できればそのようなテストは書かないようにクラス設計すべきです。


CC BY-SA 3.0
2017-04-25T06:59:28.777
34265
2017-04-25T06:59:28.777
19925
34243
answer