2009-08-04 10 views
2

この投稿の背景情報は以下のとおりです。この優れた記事でSQLiteユニットのテストNHibernateで生成されたカスケード関係

http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx)著者はNHibernateはを使用している場合、我々は、一般的に3つしか物事をテストしたい」と主張している:あなたはちょうどあなたが好きなら、質問にスキップすることができ、プロパティを永続化されることを
1)
2)そのカスケードは、クエリが正しい結果を返すこと) 3を期待どおりに動作 - 。)そのマッピングが完了し&正しい(暗黙の)

私のテイクは、彼がSQLiteのは、単位であるべきことを言うようになっていることです上記のすべてを行うには、選択したテストツールを使用してください。著者は、熟練したNHiberの開発者がそこに出てきていますが、記事で明示的に言っているわけではありませんが、彼は後でSQLiteの欠点を扱うことができ、またそうすべきであるということを暗示しています。

QUESTION:

はどのようにあなたは、特にそれが外部キー制約をチェックしないことを考えると、カスケード関係をテストするためのSQLiteを使用してください。あなたのモデルをテストして、外部キーの制約がdbの問題ではないことを確認しますか?

ここでは、私がカスケードの動作をテストするために考えたいくつかのユニットテストを示します。このモデルは、単純に、ゼロから複数のStaffMembersを持ち、カスケードをNONEに設定できるDepartmentです。

[Test] 
    public void CascadeSaveIsNone_NewDepartmentWithFetchedStaff_CanSaveDepartment() 
    { 
     _newDept.AddStaff(_fetchedStaff); 
     Assert.That(_newDept.IsTransient(), Is.True); 

     _reposDept.SaveOrUpdate(_newDept); 
     _reposDept.DbContext.CommitChanges(); 

     Assert.That(_newDept.IsTransient(), Is.False); 
    } 

    [Test] 
    public void CascadeSaveIsNone_NewDepartmentWithFetchedStaff_CannotSaveNewStaff() 
    { 
     _newDept.AddStaff(_newStaff); 
     Assert.That(_newDept.IsTransient(), Is.True); 
     Assert.That(_newStaff.IsTransient(), Is.True); 

     _reposDept.SaveOrUpdate(_newDept); 
     _reposDept.DbContext.CommitChanges(); 

     Assert.That(_newDept.IsTransient(), Is.False); 
     Assert.That(_newStaff.IsTransient(), Is.True); 
    } 

    [Test] 
    public void CascadeDeleteIsNone_FetchedDepartmentWithFetchedStaff_Error() 
    { 
     _fetchedDept.AddStaff(_fetchedStaff); 
     _reposDept.SaveOrUpdate(_fetchedDept); 
     _reposStaff.DbContext.CommitChanges(); 

     _reposDept.Delete(_fetchedDept); 
     var ex = Assert.Throws<GenericADOException>(() => _reposDept.DbContext.CommitChanges()); 

     Console.WriteLine(ex.Message); 
     Assert.That(ex.Message, Text.Contains("could not delete:")); 
     Console.WriteLine(ex.InnerException.Message); 
     Assert.That(ex.InnerException.Message, Text.Contains("The DELETE statement conflicted with the REFERENCE constraint")); 
    } 

    [Test] 
    public void Nullable_NewDepartmentWithNoStaff_CanSaveDepartment() 
    { 
     Assert.That(_newDept.Staff.Count(), Is.EqualTo(0)); 

     var fetched = _reposDept.SaveOrUpdate(_newDept); 
     Assert.That(fetched.IsTransient(), Is.EqualTo(false)); 
     Assert.That(fetched.Staff.Count(), Is.EqualTo(0)); 
    } 

3番目のテストは、「.._ FetchedDepartmentWithFetchedStaff_Errorは、」SQL Serverに対して動作しますが、後者は外部キー制約をチェックしていないためのSQLiteません。

ここに、関係の反対側のテストがあります。 StaffMemberには1つのDepartmentがあり、カスケードはNONEに設定されています。

[Test] 
    public void CascadeSaveIsNone_NewStaffWithFetchedDepartment_CanSaveStaff() 
    { 
     _newStaff.Department = _fetchedDept; 
     _reposStaff.SaveOrUpdate(_newStaff); 
     _reposStaff.DbContext.CommitChanges(); 

     Assert.That(_newStaff.Id, Is.GreaterThan(0)); 
    } 

    [Test] 
    public void CascadeSaveIsNone_NewStaffWithNewDepartment_Error() 
    { 
     _newStaff.Department = _newDept; 
     Assert.That(_newStaff.IsTransient(), Is.True); 

     var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff)); 
     Console.WriteLine(ex.Message); 
     Assert.That(ex.Message, Text.Contains("not-null property references a null or transient value")); 
    } 

    [Test] 
    public void CascadeDeleteIsNone_FetchedStaffWithFetchedDepartment_DeletesTheStaff_DoesNotDeleteTheDepartment() 
    { 
     _newStaff.Department = _fetchedDept; 
     _reposStaff.SaveOrUpdate(_newStaff); 
     _reposStaff.DbContext.CommitChanges(); 

     _reposStaff.Delete(_newStaff); 
     Assert.That(_reposStaff.Get(_newStaff.Id), Is.Null); 
     Assert.That(_reposDept.Get(_fetchedDept.Id), Is.EqualTo(_fetchedDept)); 
    } 

    [Test] 
    public void NotNullable_NewStaffWithUnknownDepartment_Error() 
    { 
     var noDept = new Department("no department"); 
     _newStaff.Department = noDept; 

     var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff)); 
     Console.WriteLine(ex.Message); 
     Assert.That(ex.Message, Text.Contains("not-null property references a null or transient")); 
    } 

    [Test] 
    public void NotNullable_NewStaffWithNullDepartment_Error() 
    { 
     var noDept = new Department("no department"); 
     _newStaff.Department = noDept; 

     var ex = Assert.Throws<PropertyValueException>(() => _reposStaff.SaveOrUpdate(_newStaff)); 
     Console.WriteLine(ex.Message); 
     Assert.That(ex.Message, Text.Contains("not-null property references a null or transient")); 
    } 

これらのテストは、Sql ServerとSQLiteに対して成功しました。 SQLiteテストを信頼できますか?これらの価値あるテストはありますか?

乾杯、
Berryl

答えて

3

私はそれはNHibernateのマッピングをテストについてです記事を理解しています。私の意見では、これはdb関連の問題とは関係ありませんが、マッピングで設定したnhibernate属性をテストすることとは関係ありません。無効なデータを作成することは不可能であると主張する必要はありません。コードで目的の結果が作成されたことを証明するだけで済みます。カスケード、カスケード削除、削除 - 孤立をテストできます。あなたがsqliteを使っているテストでそれをやりたいと思っています。しかし、3番目のテストでは制約をテストしようとしていますが、これは何の不安もありません。

Db制約をテストする場合は、実際にsqliteではなくプロダクションデータベースを使用する必要があります。あなたは休止状態の有無にかかわらずそれを行うことができますが、これはあなたのマッピングとは関係ありません。 一方、あなたが本当にSQLiteで外部キーテストのためのworkarroundを望むなら、これを使用しようとする可能性がありますforeign_key_trigger_generator。私は試していませんが、参照されたPkの存在を保証するbefore-insert-triggersを生成するようです。 おそらく、あなたはこのツールが有用なコメントを書くことができました。

関連する問題