2012-04-04 3 views
0

コントローラからdeleteメソッドをテストしようとしています。ユニットテストDeleteコントローラメソッド

[TestMethod()] 
    [DeploymentItem("Courses.sdf")] 
    public void RemoveCourseConfirmedTest() 
    { 

     CoursesController target = new CoursesController(); 
     int id = 50; 

     ActionResult actual; 
     CoursesDBContext db = new CoursesDBContext(); 
     Course courseToDelete = db.Courses.Find(id); 
     List<CourseMeet> meets = db.Meets.Where(a => a.courseID == id).ToList(); 
     actual = target.RemoveCourseConfirmed(courseToDelete); 
     foreach (CourseMeet meet in meets) 
     { 
      Assert.IsFalse(db.Meets.Contains(meet)); 
     } 
     Assert.IsFalse(db.Courses.Contains(courseToDelete)); 

    } 

これは、コントローラのメソッド

[HttpPost, ActionName("RemoveCourse")] 
    public ActionResult RemoveCourseConfirmed(Course course) 
    { 
     try 
     { 
      db.Entry(course).State = EntityState.Deleted; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     catch (DbUpdateConcurrencyException) 
     { 
      return RedirectToAction("RemoveMeet", new System.Web.Routing.RouteValueDictionary { { "concurrencyError", true } }); 
     } 
     catch (DataException) 
     { 
      ModelState.AddModelError(string.Empty, "Unable to save changes. Try again."); 
      return View(course); 
     } 

    } 

あるしかし、私は、私は次の例外を取得し、テストケースを実行すると:

は、私は次のテストケースを持っています。

System.InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker. 

私は、デバッガによるテストを実行し、問題が次の行にしていることが見つかりました:なぜこれが起こっている

db.Entry(course).State = EntityState.Deleted; 

私はわかりません。

+0

ユニットテストでは、DBコンテキストをモックし、実行中にそのコンテキストで実行される各メソッドの期待値を設定する必要があります。定義済みの戻りデータを設定します。 Contextをモックし、EntryとSaveChangesの期待値を設定します。あなたが現在やっているのは、コントローラー方式以上のテストを行う統合テストを作成することですが、DBコンテキストの統合もテストします。 – Nope

答えて

2

私がここで見る最大の問題は、あなたがデータベースに対して直接テストしていることです。あなたの単体テストは特にデータベースの依存関係を模倣するべきです。

しかし、このようにしてデッドセットした場合、テストではCoursesDBContextが開かれ、テスト対象のコードがCoursesDBContextを使用しているように見えます。つまり、異なるエンティティから同じエンティティを参照できないためです。あなたのコンテキストをクラスに渡すための何らかの方法が必要です(パブリックプロパティまたはパラメータを渡す)

+0

ありがとうございます。私は将来を考えています。 – keshav

関連する問題