2017-05-22 10 views
2

私は多くのフィールドを持つ構造体のコンストラクタをユニットテストしようとしています。コンストラクタがすべての期待される検証を実行して、複数の失敗シナリオのための単一のフィールドをテストしていることを確認したい。ユニットテスト用の構造体フィールドを変更する

私はテーブルテストを使用していますので、これをプログラム的に実行しようとしていますが、これは1フィールドエラーをテストするためにN個のパラメータフィールドを繰り返すため、テストで多くの繰り返しとノイズが発生します。例えば

func NewSomeObject(p *Params) *SomeObject { 
    ... 
} 


type SomeObject struct { 
    .. 
    Field1 string 
    Field2 string 
    Field3 string 
    ... 
    Field10 string 
} 

func TestNewSomeObject(t *testing.T) { 
    tcases := map[string]struct { 
     params *Params 
     err error 
    }{ 
     &Params{ 
      Field1: "invalid_0" // <--- making sure that this invalid field is caught 
      Field2: "valid" 
      Field3: "valid" 
      ... 
      Field10: "valid" 
     }, 
     &Params{ 
      Field1: "invalid_1" // <--- another invalid case 
      Field2: "valid" 
      Field3: "valid" 
      ... 
      Field10: "valid" 
     }, 
     &Params{ 
      Field1: "invalid_2" 
      Field2: "valid" 
      Field3: "valid" 
      ... 
      Field10: "valid" 
     }, 
     &Params{ 
      Field1: "invalid_3" 
      Field2: "valid" 
      Field3: "valid" 
      ... 
      Field10: "valid" 
     }, 
     ... 
     ... 
     ... 
    } 

    for name, tc := range tcases { 
     t.Logf("Running test %s", name) 

     s, err := NewSomeObject(tc.params) 
     if !reflect.DeepEqual(tc.err, err) { 
      t.Fatalf("Got '%v', Expected: '%v'", err, tc.err) 
     } 
    } 
} 

が入力に何度も繰り返すことなく、構造体に単一のフィールドを変更するためのより良い方法はありますか?

+1

がのコンストラクタ/関数を書き、あなただけ行うことができますParamsオブジェクトを作成するには

ParamsはField1だけを入力として受け取り、Paramsを設定します。 – Volker

+0

コメントありがとうございます。私はフィールド1だけでなく、すべてのフィールドでこれをやりたがっています...だから私はある種の閉鎖が必要でしょうか?私は自分のテストがあまりにも多くのロジックで終わることを望んでいません。 – user7467314

+0

構造体のゼロ値が有効な場合(Goでは慣習的です)、無効な値をテストしているフィールドを1つだけ設定する必要があります。 – Adrian

答えて

2

すべてのデフォルト値(有効)を設定する1つのコンストラクタを作成することで、繰り返しコードを回避できます。

コンストラクタは、作成されたオブジェクトを返す前に操作する関数を受け取ることもできます。

このようにして、テストする特定のフィールドを無効にするために必要なロジックをコーディングするだけで済みます。ここ

func CreateParamsWith(modifyParams func(*Params)) (*Params) { 
    params := &Params{ 
     Field1: "valid", 
     Field2: "valid", 
     Field3: "valid", 
     Field4: "valid", 
     Field5: "valid", 
     } 
    modifyParams(params) 
    return params 
} 

全作業コード:CreateParamsWithは次のようになります

params1 := CreateParamsWith(func(p *Params) { 
    p.Field1 = "invalid_0" 
}) 

https://play.golang.org/p/U0xhtIbQfy

関連する問題