[英]How can I write Test Unit for CRUD in MVC5 / Entity Framework 6?
我是ASP.NET MVC和單元測試的新手,我不知道如何為這些方法編寫測試方法:
// 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);
}
誰能幫助我為這些方法編寫正確而完整的測試單元?
我的第一個建議是將您的業務邏輯與管道分開。
考慮以下代碼:
// 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的一件有趣的事情是,您可以使用“異常過濾器”。 您需要兩個。
您的服務層將根據情況拋出這兩個異常。
現在,您的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);
}
}
}
這是微軟的直接方法
它與WebApi有關,工作方式與MVC相同。 我還使用了Moq或FakeItEasy之類的模擬框架,而不是創建TestStoreAppContext類。
您需要先分離本地版本,然后再執行更新過程
var localEntity = dbContext.Set<theModel>()
.Local
.FirstOrDefault(f => f.Id == theModel.Id);
if (localEntity != null)
{
dbContext.Entry(localEntity).State = EntityState.Detached;
}
dbContext.Entry(appModel).State = EntityState.Modified;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.