2017-01-20 9 views
0

私は私がこれらのメソッドのための試験方法を書くことができるかわからない、ASP.NET MVCとユニットテストに新しいです:MVC5/Entity Framework 6でCRUDのテストユニットを作成するにはどうすればよいですか?

// GET: Worts/Details 
public ActionResult Details(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 

    var wort = (from s in db.Worts 
       where s.ID == id 
       select s).FirstOrDefault(); 

    if (wort == null) 
    { 
     return HttpNotFound(); 
    } 

    return View(wort); 
} 

// GET: Worts/Create 
public ActionResult Create() 
{ 
    return View(); 
} 

// POST: Worts/Create 
[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create([Bind(Include = "ID,Title,CreateDate,ClickCount,DislikeCount,LikeCount, Creator_ID")] Wort wort) 
{ 
    if (ModelState.IsValid) 
    { 
     wort.CreateDate = DateTime.Now; 
     wort.ClickCount = 0; 
     wort.DislikeCount = 0; 
     wort.LikeCount = 0; 

     var userId = User.Identity.GetUserId(); 
     wort.Creator = db.Users.Where(x => x.ID == userId).FirstOrDefault(); 

     db.Worts.Add(wort); 
     db.SaveChanges(); 

     try 
     { 
      this.mailSender.SendEmail(wort); 
      return RedirectToAction("Index"); 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    } 
    return View(wort); 
} 

// GET: Worts/Edit/5 
public ActionResult Edit(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 

    Wort wort = db.Worts.Find(id); 

    if (wort == null) 
    { 
     return HttpNotFound(); 
    } 
    return View(wort); 
} 

// POST: Worts/Edit/5 
[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit([Bind(Include = "ID,Title,CreateDate")] Wort wort) 
{ 
    if (ModelState.IsValid) 
    { 
     db.Entry(wort).State = EntityState.Modified; 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

    return View(wort); 
} 

// GET: Worts/Delete/5 
public ActionResult Delete(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 

    Wort wort = db.Worts.Find(id); 

    if (wort == null) 
    { 
     return HttpNotFound(); 
    } 
    return View(wort); 
} 

// POST: Worts/Delete/5 
[HttpPost, ActionName("Delete")] 
[ValidateAntiForgeryToken] 
public ActionResult DeleteConfirmed(int id) 
{ 
    Wort wort = db.Worts.Find(id); 
    db.Worts.Remove(wort); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

私はテストのために、このコードを書かれているが、それは十分ではありません。

[TestMethod] 
public void Details() 
{ 
     // Arrange 
     WortsController controller = new WortsController(); 

     int id = 22; 

     // Act 
     ViewResult result = controller.Details(id) as ViewResult; 

     // Assert 
     Assert.IsNotNull("Details", result.ViewName); 
} 

[TestMethod] 
public void Create() 
{ 
     // Arrange 
     WortsController controller = new WortsController(); 

     // Act 
     ViewResult result = controller.Create(new LikeWort.Models.Wort()) as ViewResult; 

     // Assert 
     Assert.IsNotNull(result); 
} 

[TestMethod] 
public void Edit(int? id) 
{ 
     // Arrange 
     WortsController controller = new WortsController(); 

     // Act 
     ViewResult result = controller.Edit(id) as ViewResult; 

     // Assert 
     Assert.IsNotNull(result); 
} 

[TestMethod] 
public void Delete(int? id) 
{ 
     // Arrange 
     WortsController controller = new WortsController(); 

     // Act 
     ViewResult result = controller.Delete(id) as ViewResult; 

     // Assert 
     Assert.IsNotNull(result); 
} 

これらのメソッドの正確で完全なテストユニットを書くのを手伝ってくれる人はいますか?

答えて

1

私の最初のお勧めは、ビジネスロジックを配管から分離することです。

は、このコードを考えてみましょう:すべての

// GET: Worts/Details 
public ActionResult Details(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 

    var wort = (from s in db.Worts 
       where s.ID == id 
       select s).FirstOrDefault(); 

    if (wort == null) 
    { 
     return HttpNotFound(); 
    } 

    return View(wort); 
} 

まずは、独自のライブラリにデータベース呼び出しを移動してみましょう。

// GET: Worts/Details 
public ActionResult Details(int? id) 
{ 
    if (id == null) 
    { 
     return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    } 

    var wort = WortService.GetWort(id); 

    if (wort == null) 
    { 
     return HttpNotFound(); 
    } 

    return View(wort); 
} 

WortServiceにはASP.NET MVCが含まれていないため、テストするのがはるかに簡単です。

ここで定型文を見てみましょう。 ASP.NET MVCの興味深い点は、「例外フィルタ」を使用できることです。あなたは2つ必要です。

  1. コンバートArgumentExceptionがあなたのサービス層を適宜これらの2つの例外がスローされますHttpStatusCode.NotFound

に変換するMissingDataException

  • HttpStatusCode.BadRequestへ。

    今すぐあなたのMVC層だけである:

    // GET: Worts/Details 
    public ActionResult Details(int? id) 
    { 
        var wort = WortService.GetWort(id); 
        return View(wort); 
    } 
    

    それは、独自のテストを必要としないほどシンプルであること。テストの大部分はWortServiceに対するものであり、残りは実行するUIテストの対象です。


    public class WortService { 
        public LWContext dbLW = new LWContext(); 
        public Wort GetWort(int? id) 
        { 
         if (id == null) 
          throw new ArgumentNullException("id"); 
    
         var wort = (from s in dbLW.Worts where s.ID == id select s).FirstOrDefault(); 
         return wort; 
        } 
    } 
    
    
    public class ArgumentExceptionFilterAttribute : ExceptionFilterAttribute 
    { 
        public override void OnException(HttpActionExecutedContext context) 
        { 
         if (context.Exception is ArgumentException) 
         { 
          context.Response = new HttpResponseMessage(HttpStatusCode.BadRequest); 
         } 
        } 
    } 
    
  • +0

    の提案のためのおかげで、私はそれをしました。私はあなたのようなクラスを作成しましたが、私は入れません:HttpStatusCodeResult(HttpStatusCode.BadRequest)、私の新しいクラスで...どのように私はそれのためのtestMethodを書くことができますか? – Sara

    +0

    これは新しいクラスです。public class WortService { public LWContext dbLW = new LWContext();これは新しいクラスです。 public Wort GetWort(int?id) { var wort =(dbLW.Wortsの でs.ID == id が選択されています).FirstOrDefault(); return wort; } } – Sara

    +0

    GetWortはArgumentExceptionをスローします。あなたの例外フィルタはそれをHTTPステータスコードに変換します。(更新された例を参照) –

    関連する問題