0

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

次のテストケースがあります。

    [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;

なぜこれが起こっているのかわかりません。

4

1 に答える 1

2

ここで私が目にする最大の問題は、データベースに対して直接テストしていることです。単体テストでは、特にデータベースの依存関係をモックアウトする必要があります。

ただし、この方法で行き詰まっている場合、発生するエラーは、テストがを開いているという事実に起因しており、テストCoursesDBContext対象のコードは独自のを使用しているように見えますCoursesDBContext。したがって、エラーは、異なるコンテキストから同じエンティティを参照しようと試みることができないためです。コンテキストをクラスに渡す何らかの方法が必要になります(パブリックプロパティまたはパラメーターを介して渡される)

于 2012-04-04T04:51:20.087 に答える