How to mock a model in ASP.NET MVC?

I have created a custom model and I want to mock it. I am new to MVC and very new to unit testing. Most of the approaches that I have seen create an interface for the class, and then make a layout that implements the same interface. However, I cannot get this to work when I actually pass the interface to the view. A simplified example example:

Model -

public interface IContact
{
    void SendEmail(NameValueCollection httpRequestVars);
}

public abstract class Contact : IContact
{
    //some shared properties...
    public string Name { get; set; }

    public void SendEmail(NameValueCollection httpRequestVars = null)
    {
        //construct email...
    }
}

public class Enquiry : Contact
{
    //some extra properties...
}

View -

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<project.Models.IContact>" %>

<!-- other html... -->

<td><%= Html.TextBoxFor(model => ((Enquiry)model).Name)%></td>

Controller -

    [HttpPost]
    public ActionResult Index(IContact enquiry)
    {
        if (!ModelState.IsValid)
            return View(enquiry);

        enquiry.SendEmail(Request.ServerVariables);
        return View("Sent", enquiry);
    }

Device Testing -

    [Test]
    public void Index_HttpPostInvalidModel_ReturnsDefaultView()
    {
        Enquiry enquiry = new Enquiry();
        _controller.ModelState.AddModelError("", "dummy value");

        ViewResult result = (ViewResult)_controller.Index(enquiry);

        Assert.IsNullOrEmpty(result.ViewName);
    }

    [Test]
    public void Index_HttpPostValidModel_CallsSendEmail()
    {
        MockContact mock = new MockContact();

        ViewResult result = (ViewResult)_controller.Index(mock);

        Assert.IsTrue(mock.EmailSent);
    }

public class MockContact : IContact
{
    public bool EmailSent = false;

    void SendEmail(NameValueCollection httpRequestVars)
    {
        EmailSent = true;
    }
}

After HttpPost, I get the exception "Cannot create an interface instance." It seems I can’t have my cake (passing the model) and eat it (skip the layout for unit testing). Maybe there is a better approach to testing modules related to views?

thank,

Honey

+3
3

, , . .

, SendEmail. , , EmailService.

:

(SOC), MVC, MVP, MVVM ( , , , , , ). , 3 .

Domain Driven Design (DDD) -, # (POCO), Persistent Ignorant (PI). , POCO/PI, , , , , 1 .

, , View, Domain Model Physical Storage Model , 1 .

View, Domain Storage, 3 . ViewModels , . , , , / .

, , -. , / / / . . . ViewModels, MVC.

, FluentValidation ( , ), - . MVC3 , .

, . , , PI , , , . , Linq2Sql, EntityFramework (EF) .., , , , .

, , MVC

  • EF , EF - (BE), BE EF . (, - , , ).

  • BE ViewModel (VM) ,

  • (, ProductVM)

  • ( / )

  • ProductVM ProductBE , - ValidationFactory.Validate(ProductBE), ,

  • ProductBE , ProductBE EF .

2016 edit: Interface, .

+9

:

public ActionResult Index(IContact enquiry)

MVC . MVC , IContract.

? . MVC.

, , , , , mocks.

public class Contact
{
    //some shared properties...
    public string Name { get; set; }

    public virtual void SendEmail(NameValueCollection httpRequestVars = null)
    {
        //construct email...
    }
}

public class MockContact
{
    //some shared properties...
    public string Name { get; set; }
    public bool EmailSent {get;private set;}

    public override void SendEmail(NameValueCollection vars = null)
    {
       EmailSent = true;
    }
}

public ActionResult Index(Contact enquiry)
0

You can use interfaces.

See: http://mvcunity.codeplex.com/

0
source

Source: https://habr.com/ru/post/1774357/


All Articles