【问题标题】:Unit testing CRUD operation in visual studio 2012Visual Studio 2012 中的单元测试 CRUD 操作
【发布时间】:2013-09-30 09:44:30
【问题描述】:

我正在 Visual Studio 2012 中测试创建类

我的控制器类是:

  public ActionResult Create()
    {
        return View();
    }

    //
    // POST: /Member/Create

    [HttpPost]
    public ActionResult Create(Member member)
    {
        if (ModelState.IsValid)
        {
            db.Members.Add(member);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(member);
    }

而测试类是:

[TestClass]
public class MemberTest
{

    [TestMethod]
    public void Create(Member mem)
    {
        mem.MemID = 123;
        mem.MemName = "sruthy";


        /// dont know what is writing.

    }
}

SampleDataContext.cs

public class SampleDataContext:DbContext
{
    public DbSet<Member> Members { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

我被困在测试用例中,请帮助我。

【问题讨论】:

    标签: c# entity-framework unit-testing asp.net-mvc-4


    【解决方案1】:

    首先 - 为您的数据访问代码创建一个抽象(模拟 DbContext 不是很方便):

    public interface IMemberRepository
    {
        void Add(Member member);
    }
    

    让你的控制器依赖它

    public MemberController(IMemberRepository repository)
    {
        this.repository = repository;
    }
    

    这将允许轻松地模拟数据访问代码。接下来 - 编写验证控制器行为的测试(我在这里使用 NUnit 和 Moq):

    private MemberController controller;
    private Mock<IMemberRepository> repositoryMock;
    private Member member;
    
    [SetUp]
    public void Setup()
    {
        repositoryMock = new Mock<IMemberRepository>();
        controller = new MemberController(repositoryMock.Object);
        member = new Member { MemID = 123, MemName = "sruthy" };
    }
    
    [Test]
    public void ShouldCreateMemberWhenItIsValid()
    {
        var result = (RedirectToRouteResult)controller.Create(member);
        Assert.That(result.RouteValues["action"], Is.EqualTo("Index"));
        repositoryMock.Verify(r => r.Add(member));
    }
    
    [Test]
    public void ShouldNotCreateMemberWhenItIsNotValid()
    {
        controller.ModelState.AddModelError("MemName", "Something wrong");
        var result = (ViewResult)controller.Create(member);
        Assert.That(result.ViewName, Is.Empty);
    }
    

    并编写实现:

    [HttpPost]
    public ActionResult Create(Member member)
    {
        if (ModelState.IsValid)
        {
            repository.Add(member);
            return RedirectToAction("Index");
        }
    
        return View(member);
    }
    

    【讨论】:

    • 这正是我想写的答案
    • 这是否也需要[TearDown]方法进行清理?
    • @christiandev 因此在每次测试运行之前分配给字段的新值,您不需要在此处进行 TearDown
    • 什么是“RedirectToRouteResult”?
    【解决方案2】:

    我对单元测试的理解是:“只测试你的方法在做什么”所以我认为你必须测试你的方法是否做得很好:

    • ModelState.IsValid

    • db.Members.Add(member)

    • db.SaveChanges()

    但不是 ModelState 或 DbContext 的良好行为。这些在他们自己的单元测试中进行测试。您只需断言调用已完成。

    要执行这种测试,您必须使用依赖注入模式并用模拟替换真实的 DbContext。这些模拟只是断言调用执行得很好,而不涉及真正的 dbContext。

    我不是单元测试方面的专家,但我认为您必须考虑所有架构才能解耦对象。这允许您用模拟替换真实对象。

    【讨论】:

      猜你喜欢
      • 2013-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      相关资源
      最近更新 更多