C# MVC最小起订量单元试验无效法

C# MVC最小起订量单元试验无效法,c#,asp.net-mvc,unit-testing,asp.net-mvc-4,moq,C#,Asp.net Mvc,Unit Testing,Asp.net Mvc 4,Moq,我有一个程序的表单,我想用Moq进行单元测试。 我有用于单元测试的工作代码Get WebApi方法,这些方法工作得很好,但我不知道如何在MVC控制器中编写一篇关于void方法的文章 我想测试ModelState.IsValid,如果无效则返回异常 控制器 public class HomeController : Controller { private IEditDataRepository _editDataRepository; public HomeController

我有一个程序的表单,我想用Moq进行单元测试。 我有用于单元测试的工作代码Get WebApi方法,这些方法工作得很好,但我不知道如何在MVC控制器中编写一篇关于void方法的文章

我想测试ModelState.IsValid,如果无效则返回异常

控制器

public class HomeController : Controller
{
    private IEditDataRepository _editDataRepository;

    public HomeController()
    {
        //Default Constructor
    }

    //Dependency Injection using Unity.MVC5 NuGet Package
    public HomeController(IEditDataRepository editDataRepository)
    {
        _editDataRepository = editDataRepository;
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public void Edit([Bind(Include = "Field1,Field2")] FormViewModel model)
    {
        if (ModelState.IsValid)
        {
            _editDataRepository.Edit(model);
        }
        else
        {
            throw new HttpException(400, "ModelState Invalid");
        }
    }
}
public class HomeController : Controller
{
    private IEditDataRepository _editDataRepository;

    //Dependency Injection using Unity.MVC5 NyGet Packages
    public HomeController(IEditDataRepository editDataRepository)
    {
        _editDataRepository = editDataRepository;
    }

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

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "Field1,Field2")] FormViewModel model)
    {
        if (ModelState.IsValid)
        {
            _editDataRepository.Edit(model);
            return new HttpStatusCodeResult(HttpStatusCode.OK);
        }
        else
        {
            throw new HttpException(400, "ModelState Invalid");
        }
    }
}
存储库

public class EditDataRepository : IEditDataRepository, IDisposable
{
    private DBEntities db = new DBEntities();

    public void Edit(FormViewModel model)
    {            
        db.MyProcedure(model.Field1,model.Field2);
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                db.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
public class EditDataRepository : IEditDataRepository, IDisposable
{
    private DBEntities db = new DBEntities();

    public void Edit(FormViewModel model)
    {            
        db.MyProcedure(model.Field1,model.Field2);
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                db.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
单元测试

[TestClass]
public class HomeControllerTests
{
    /// <summary>
    /// Tests the Edit method is run
    /// </summary>
    [TestMethod]
    public void Edit_Method_Is_Run()
    {
        //Arrange
        var mockRepository = new Mock<IEditDataRepository>();
        mockRepository
             .Setup(x => x.Edit(It.IsAny<FormViewModel>()));
        HomeController controller = new HomeController(mockRepository.Object);

        //Act
        controller.Edit(It.IsAny<FormViewModel>());

        //Assert
        mockRepository.VerifyAll();
    }

    [TestMethod]
    public void Edit_Returns_OK()
    {
        //Arrange
        var mockRepository = new Mock<IEditDataRepository>();
        mockRepository
             .Setup(x => x.Edit(It.IsAny<FormViewModel>()));
        HomeController controller = new HomeController(mockRepository.Object);

        //Act            
        var response = controller.Edit(It.IsAny<FormViewModel>());

        //Assert
        Assert.IsInstanceOfType(response, typeof(HttpStatusCodeResult));
        var httpResult = response as HttpStatusCodeResult;
        Assert.AreEqual(200, httpResult.StatusCode);
    }

    /// <summary>
    /// Tests the Edit method throws exception
    /// </summary>
    [TestMethod]
    [ExpectedException(typeof(HttpResponseException))]
    public void Edit_Returns_Exception()
    {
        var mockRepository = new Mock<IEditDataRepository>();
        mockRepository
            .Setup(x => x.Edit(It.IsAny<FormViewModel>()))
            .Throws(new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)));
        HomeController controller = new HomeController(mockRepository.Object);

        //Act            
        var response = controller.Edit(It.IsAny<FormViewModel>());

        //Assert
        Assert.IsInstanceOfType(response, typeof(HttpResponseException));
    }
}
我可以在这里做一些设置,但之后我不确定。 如何检查ModelState.IsValid和not valid(返回异常)

[TestMethod]
公共空间
{
//安排
var mockRepository1=new Mock();
模拟存储1
.Setup(x=>x.Edit(It.IsAny());
HomeController=新的HomeController(mockRepository1.Object);
//表演
controller.Edit(It.IsAny());
//断言
}
[TestMethod]
公共空间
{
//安排
var mockRepository1=new Mock();
模拟存储1
.Setup(x=>x.Edit(It.IsAny());
HomeController=新的HomeController(mockRepository1.Object);
controller.ModelState.AddModelError(“错误”,“无效模型”);
//行动/主张
var ex=Assert.Throws(()=>controller.Edit(It.IsAny());
断言相等(400,ex.ErrorCode);
}

另外,我建议您不要在存储库中实现Dispose/Finalize模式。除非它是真正的非托管资源,而事实似乎并非如此。有更多的细节。

我想我应该分享我的路线。我决定不返回void,而是返回一个HttpStatusCode。 我已经熟悉如何测试它了

控制器

public class HomeController : Controller
{
    private IEditDataRepository _editDataRepository;

    public HomeController()
    {
        //Default Constructor
    }

    //Dependency Injection using Unity.MVC5 NuGet Package
    public HomeController(IEditDataRepository editDataRepository)
    {
        _editDataRepository = editDataRepository;
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public void Edit([Bind(Include = "Field1,Field2")] FormViewModel model)
    {
        if (ModelState.IsValid)
        {
            _editDataRepository.Edit(model);
        }
        else
        {
            throw new HttpException(400, "ModelState Invalid");
        }
    }
}
public class HomeController : Controller
{
    private IEditDataRepository _editDataRepository;

    //Dependency Injection using Unity.MVC5 NyGet Packages
    public HomeController(IEditDataRepository editDataRepository)
    {
        _editDataRepository = editDataRepository;
    }

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

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "Field1,Field2")] FormViewModel model)
    {
        if (ModelState.IsValid)
        {
            _editDataRepository.Edit(model);
            return new HttpStatusCodeResult(HttpStatusCode.OK);
        }
        else
        {
            throw new HttpException(400, "ModelState Invalid");
        }
    }
}
存储库

单元测试

[TestClass]
public class HomeControllerTests
{
    /// <summary>
    /// Tests the Edit method is run
    /// </summary>
    [TestMethod]
    public void Edit_Method_Is_Run()
    {
        //Arrange
        var mockRepository = new Mock<IEditDataRepository>();
        mockRepository
             .Setup(x => x.Edit(It.IsAny<FormViewModel>()));
        HomeController controller = new HomeController(mockRepository.Object);

        //Act
        controller.Edit(It.IsAny<FormViewModel>());

        //Assert
        mockRepository.VerifyAll();
    }

    [TestMethod]
    public void Edit_Returns_OK()
    {
        //Arrange
        var mockRepository = new Mock<IEditDataRepository>();
        mockRepository
             .Setup(x => x.Edit(It.IsAny<FormViewModel>()));
        HomeController controller = new HomeController(mockRepository.Object);

        //Act            
        var response = controller.Edit(It.IsAny<FormViewModel>());

        //Assert
        Assert.IsInstanceOfType(response, typeof(HttpStatusCodeResult));
        var httpResult = response as HttpStatusCodeResult;
        Assert.AreEqual(200, httpResult.StatusCode);
    }

    /// <summary>
    /// Tests the Edit method throws exception
    /// </summary>
    [TestMethod]
    [ExpectedException(typeof(HttpResponseException))]
    public void Edit_Returns_Exception()
    {
        var mockRepository = new Mock<IEditDataRepository>();
        mockRepository
            .Setup(x => x.Edit(It.IsAny<FormViewModel>()))
            .Throws(new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)));
        HomeController controller = new HomeController(mockRepository.Object);

        //Act            
        var response = controller.Edit(It.IsAny<FormViewModel>());

        //Assert
        Assert.IsInstanceOfType(response, typeof(HttpResponseException));
    }
}
[TestClass]
公共类家庭控制器测试
{
/// 
///测试是否运行编辑方法
/// 
[测试方法]
public void Edit_方法_是_Run()
{
//安排
var mockRepository=new Mock();
模拟存储库
.Setup(x=>x.Edit(It.IsAny());
HomeController=新的HomeController(mockRepository.Object);
//表演
controller.Edit(It.IsAny());
//断言
mockRepository.VerifyAll();
}
[测试方法]
public void Edit_返回_OK()
{
//安排
var mockRepository=new Mock();
模拟存储库
.Setup(x=>x.Edit(It.IsAny());
HomeController=新的HomeController(mockRepository.Object);
//表演
var response=controller.Edit(It.IsAny());
//断言
IsInstanceOfType(响应,类型(HttpStatusCodeResult));
var httpResult=作为HttpStatusCodeResult的响应;
AreEqual(200,httpResult.StatusCode);
}
/// 
///测试编辑方法是否引发异常
/// 
[测试方法]
[预期异常(类型(HttpResponseException))]
public void Edit_返回_异常()
{
var mockRepository=new Mock();
模拟存储库
.Setup(x=>x.Edit(It.IsAny()))
.Throws(新的HttpResponseException(新的HttpResponseMessage(HttpStatusCode.BadRequest)));
HomeController=新的HomeController(mockRepository.Object);
//表演
var response=controller.Edit(It.IsAny());
//断言
IsInstanceOfType(响应,类型(HttpResponseException));
}
}

只需将无效的
FormViewModel
传递给编辑操作。或者手动设置modelstate:好奇,为什么您在控制器上的操作无效?Nkosi-不太确定。我想在我真正知道自己在做什么之前,我只是在使用旧代码。你认为这应该是什么,ActionResult?我想我这么做是因为它只是在运行更新,我只需要知道它是否失败。太好了。谢谢你。是否有对有效模型状态的测试,或者我应该用其他方法替换void方法?可以通过检查您的模拟来验证有效模型的测试。如果模型有效,则称为