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.
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.
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 .
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);
}
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With