devfunkd
devfunkd

Reputation: 3234

MVC Controller Unit Test

I am trying to test my controller and quite new to this testing. Using NUnit and Moq I keep getting a null result. Here is my test, am I missing a step? like I mentioned it's my first project.

[TestFixture]
class CustomerServiceTests
{
    public Mock<IRepository<Customer>> CustomerRepository = new Mock<IRepository<Customer>>(); 

    public Customer Customer;

    [SetUp]
    public void Setup()
    {
        Customer = new Customer()
        {
            Id = 1 << Can I set the ID?
            Address = "3 Lakeview Terrace",
            City = "New York",
            Email = "[email protected]",
            FirstName = "Joe",
            LastName = "Dirt",
            Phone = "888-888-8888",
            Province = "NY"
        };         
    }


    [Test]
    public void CanCreateCustomer()
    {
        // ARRANGE
        var controller = new CustomerController(CustomerRepository.Object);
        controller.Create(Customer);

        // ACT
        var customer = CustomerRepository.Setup(c => c.Find(1)).Returns(new Customer());

        // ASSERT
        Assert.AreEqual(Customer, customer);
    }      
}

CONTROLLER

// POST: /Customer/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Customer customer)
    {
        if (ModelState.IsValid)
        {
            _customerRepository.Add(customer);
            return RedirectToAction("Index");
        }
        return View(customer);
    }

IREPOSITORY

public interface IRepository<T>  where T : class 
    {
        IQueryable<T> Get { get; }
        T Find(object[] keyValues);
        T Find(int id);
        void Add(T entity);
        void Update(T entity);
        void AddOrUpdate(T entity);
        void Remove(object[] keyValues);
        void Remove(T entity);

    }

Upvotes: 0

Views: 231

Answers (2)

Rikard
Rikard

Reputation: 3869

To test the viewName you need to change your code a little bit.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Customer customer)
{
    if (ModelState.IsValid)
    {
        _customerRepository.Add(customer);
        return RedirectToAction("Index");
    }
    return View("Create", customer);
}

Test:

[Test]
public void ReturnView()
{
   // ACT
   var controller = new CustomerController(CustomerRepository.Object);
   var result = controller.Create(Customer);

   // ASSERT
   Assert.AreEqual("Create", ((ViewResult)result).ViewName);
}

To test the returned data:

[TestMethod]
public void TestMethod2()
{
    var controller = new CustomerController();
    var result = controller.Create(Customer);

    Assert.AreEqual(1, ((Asd)((ViewResult)result).ViewData.Model).Id);
 }

Upvotes: 0

Rikard
Rikard

Reputation: 3869

Your test method should look like this:

[Test]
public void CanCreateCustomer()
{
    // ACT
    var controller = new CustomerController(CustomerRepository.Object);
    controller.Create(Customer);

    // VERIFY
    CustomerRepository.Verify(c => c.Add(It.Is.Any<Customer>(),Times.Once()));
}

To add an error to the modelstate you can do it like this:

controller .ModelState.AddModelError("key", "error message");

Otherwise the modelState is valid.

Upvotes: 2

Related Questions