Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing CRUD operation in visual studio 2012

I am testing the create class in Visual Studio 2012

My controller class is:

  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);
    }

And test class is:

[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>();
    }
}

I am stuck in test case please help me.

like image 345
neel Avatar asked Sep 30 '13 09:09

neel


People also ask

How do I run a unit test in Visual Studio?

Run tests in Test Explorer If Test Explorer is not visible, choose Test on the Visual Studio menu, choose Windows, and then choose Test Explorer (or press Ctrl + E, T). As you run, write, and rerun your tests, the Test Explorer displays the results in a default grouping of Project, Namespace, and Class.

How do you write unit test cases in Visual Studio 2017?

In the new project dialog box, find the unit test project to use. Type test in the search box to find a unit test project template for the test framework you want to use, such as MSTest (C#) or the Native Unit Test project (C++), and select it. Starting in Visual Studio 2017 version 14.8, the .


Video Answer


2 Answers

First - create an abstraction for your data access code (mocking DbContext is not very convenient thing):

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

and make your controller depend on it

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

This will allow mock data access code easily. Next - write tests which verify controller behavior (I use NUnit and Moq here):

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);
}

And write implementation:

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

    return View(member);
}
like image 157
Sergey Berezovskiy Avatar answered Oct 31 '22 14:10

Sergey Berezovskiy


What I understood in unit testing is : "test only what your method is doing" So I think you have to test your method is doing well:

  • ModelState.IsValid

  • db.Members.Add(member)

  • db.SaveChanges()

But not the good behavior of ModelState or DbContext. These are tested in their own unit tests. You have to assert only the call is done.

To perform this kind of test you have to use the Dependency injection pattern and replace the real DbContext by mocks. These mocks are just asserting the call is well executed without involving the real dbContext.

I'm not a specialist in unit testing but I think you have to think all your architecture in order to decouple your objects. This allow you to replace real objects by mocks.

like image 29
bAN Avatar answered Oct 31 '22 14:10

bAN