Unit testing for entity Framework validation - asp.net-mvc

I am trying to create a unit test for the validation of an Entity Framework object. I found this link:
https://stackoverflow.com/a/11514648/2486661 but the validation for me never get the value false. I am using data annotations in the properties of the entity object. For this I create a MetaData object for including the annotations and annotated the entity object like this:
[MetadataType(typeof(MyEntityObjectMetaData))]
public partial class MyEntityObject
{
}
My validation annotations are like this:
public class MyEntityObjectMetaData
{
[StringLength(8, ErrorMessage = "Invalid Length for myProperty.")]
public String myProperty { get; set; }
}
And the code for the unit test:
[TestMethod]
public void TestMethod1()
{
MyEntityObject myEntityObject = new MyEntityObject();
myEntityObject.myProperty = "1234567890";
var context = new ValidationContext(myEntityObject, null, null);
var results = new List<ValidationResult>();
var actual = Validator.TryValidateObject(myEntityObject, context, results);
var expected = false;
Assert.AreEqual(expected, actual);
}
I do not understand why the validation of the object return the value true if I have an invalid value for the property. Thanks for any help.

Here is an example of the code as part of a series of tests I run against each View Model, including a test to make sure the expected property names are there.
/// <summary>
/// Check expected properties exist.
/// </summary>
[Test]
public void Check_Expected_Properties_Exist()
{
// Get properties.
PropertyInfo propInfoFirstName = typeof(ViewModels.MyModel).GetProperty("FirstName");
PropertyInfo propInfoLastName = typeof(ViewModels.MyModel).GetProperty("LastName");
// Assert.
Assert.IsNotNull(propInfoFirstName);
Assert.IsNotNull(propInfoLastName);
}
Hope this helps.

I resolve the problem using the DBContext object like this:
MyEntityObject myEntityObject = new MyEntityObject();
myEntityObject.myProperty = "1234567890";
var dbContext = new DbContext(MyEntityObject, true);
int errors = dbContext.GetValidationErrors().Count();
IEnumerable<DbEntityValidationResult> validationResults =
dbContext.GetValidationErrors();
DbValidationError validationError = validationResults.First().ValidationErrors.First();
Assert.AreEqual(1, errors);
Assert.AreEqual("myProperty", validationError.PropertyName);
MyEntityObject is a subclass of ObjectContext class and is auto generated by the Entity Framework.
I still don't understand why using the Validator.TryValidateObject method doesn't work.

You have to tell the validator to validate all properties. The dbcontext will track changes to the entity and pass specific properties to the validator.
In EF 6 you would call
var actual = Validator.TryValidateObject(myEntityObject, context, results, validateAllProperties: true);

Related

MVC Full Calendar Error [duplicate]

I am trying to do a simple JSON return but I am having issues I have the following below.
public JsonResult GetEventData()
{
var data = Event.Find(x => x.ID != 0);
return Json(data);
}
I get a HTTP 500 with the exception as shown in the title of this question. I also tried
var data = Event.All().ToList()
That gave the same problem.
Is this a bug or my implementation?
It seems that there are circular references in your object hierarchy which is not supported by the JSON serializer. Do you need all the columns? You could pick up only the properties you need in the view:
return Json(new
{
PropertyINeed1 = data.PropertyINeed1,
PropertyINeed2 = data.PropertyINeed2
});
This will make your JSON object lighter and easier to understand. If you have many properties, AutoMapper could be used to automatically map between DTO objects and View objects.
I had the same problem and solved by using Newtonsoft.Json;
var list = JsonConvert.SerializeObject(model,
Formatting.None,
new JsonSerializerSettings() {
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});
return Content(list, "application/json");
This actually happens because the complex objects are what makes the resulting json object fails.
And it fails because when the object is mapped it maps the children, which maps their parents, making a circular reference to occur. Json would take infinite time to serialize it, so it prevents the problem with the exception.
Entity Framework mapping also produces the same behavior, and the solution is to discard all unwanted properties.
Just expliciting the final answer, the whole code would be:
public JsonResult getJson()
{
DataContext db = new DataContext ();
return this.Json(
new {
Result = (from obj in db.Things select new {Id = obj.Id, Name = obj.Name})
}
, JsonRequestBehavior.AllowGet
);
}
It could also be the following in case you don't want the objects inside a Result property:
public JsonResult getJson()
{
DataContext db = new DataContext ();
return this.Json(
(from obj in db.Things select new {Id = obj.Id, Name = obj.Name})
, JsonRequestBehavior.AllowGet
);
}
To sum things up, there are 4 solutions to this:
Solution 1: turn off ProxyCreation for the DBContext and restore it in the end.
private DBEntities db = new DBEntities();//dbcontext
public ActionResult Index()
{
bool proxyCreation = db.Configuration.ProxyCreationEnabled;
try
{
//set ProxyCreation to false
db.Configuration.ProxyCreationEnabled = false;
var data = db.Products.ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(ex.Message);
}
finally
{
//restore ProxyCreation to its original state
db.Configuration.ProxyCreationEnabled = proxyCreation;
}
}
Solution 2: Using JsonConvert by Setting ReferenceLoopHandling to ignore on the serializer settings.
//using using Newtonsoft.Json;
private DBEntities db = new DBEntities();//dbcontext
public ActionResult Index()
{
try
{
var data = db.Products.ToList();
JsonSerializerSettings jss = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
var result = JsonConvert.SerializeObject(data, Formatting.Indented, jss);
return Json(result, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(ex.Message);
}
}
Following two solutions are the same, but using a model is better because it's strong typed.
Solution 3: return a Model which includes the needed properties only.
private DBEntities db = new DBEntities();//dbcontext
public class ProductModel
{
public int Product_ID { get; set;}
public string Product_Name { get; set;}
public double Product_Price { get; set;}
}
public ActionResult Index()
{
try
{
var data = db.Products.Select(p => new ProductModel
{
Product_ID = p.Product_ID,
Product_Name = p.Product_Name,
Product_Price = p.Product_Price
}).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(ex.Message);
}
}
Solution 4: return a new dynamic object which includes the needed properties only.
private DBEntities db = new DBEntities();//dbcontext
public ActionResult Index()
{
try
{
var data = db.Products.Select(p => new
{
Product_ID = p.Product_ID,
Product_Name = p.Product_Name,
Product_Price = p.Product_Price
}).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(ex.Message);
}
}
JSON, like xml and various other formats, is a tree-based serialization format. It won't love you if you have circular references in your objects, as the "tree" would be:
root B => child A => parent B => child A => parent B => ...
There are often ways of disabling navigation along a certain path; for example, with XmlSerializer you might mark the parent property as XmlIgnore. I don't know if this is possible with the json serializer in question, nor whether DatabaseColumn has suitable markers (very unlikely, as it would need to reference every serialization API)
add [JsonIgnore] to virtuals properties in your model.
Using Newtonsoft.Json: In your Global.asax Application_Start method add this line:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
Its because of the new DbContext T4 template that is used for generating the EntityFramework entities. In order to be able to perform the change tracking, this templates uses the Proxy pattern, by wrapping your nice POCOs with them. This then causes the issues when serializing with the JavaScriptSerializer.
So then the 2 solutions are:
Either you just serialize and return the properties you need on the client
You may switch off the automatic generation of proxies by setting it on the context's configuration
context.Configuration.ProxyCreationEnabled = false;
Very well explained in the below article.
http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/
Provided answers are good, but I think they can be improved by adding an "architectural" perspective.
Investigation
MVC's Controller.Json function is doing the job, but it is very poor at providing a relevant error in this case. By using Newtonsoft.Json.JsonConvert.SerializeObject, the error specifies exactly what is the property that is triggering the circular reference. This is particularly useful when serializing more complex object hierarchies.
Proper architecture
One should never try to serialize data models (e.g. EF models), as ORM's navigation properties is the road to perdition when it comes to serialization. Data flow should be the following:
Database -> data models -> service models -> JSON string
Service models can be obtained from data models using auto mappers (e.g. Automapper). While this does not guarantee lack of circular references, proper design should do it: service models should contain exactly what the service consumer requires (i.e. the properties).
In those rare cases, when the client requests a hierarchy involving the same object type on different levels, the service can create a linear structure with parent->child relationship (using just identifiers, not references).
Modern applications tend to avoid loading complex data structures at once and service models should be slim. E.g.:
access an event - only header data (identifier, name, date etc.) is loaded -> service model (JSON) containing only header data
managed attendees list - access a popup and lazy load the list -> service model (JSON) containing only the list of attendees
Avoid converting the table object directly. If relations are set between other tables, it might throw this error.
Rather, you can create a model class, assign values to the class object and then serialize it.
I'm Using the fix, Because Using Knockout in MVC5 views.
On action
return Json(ModelHelper.GetJsonModel<Core_User>(viewModel));
function
public static TEntity GetJsonModel<TEntity>(TEntity Entity) where TEntity : class
{
TEntity Entity_ = Activator.CreateInstance(typeof(TEntity)) as TEntity;
foreach (var item in Entity.GetType().GetProperties())
{
if (item.PropertyType.ToString().IndexOf("Generic.ICollection") == -1 && item.PropertyType.ToString().IndexOf("SaymenCore.DAL.") == -1)
item.SetValue(Entity_, Entity.GetPropValue(item.Name));
}
return Entity_;
}
You can notice the properties that cause the circular reference. Then you can do something like:
private Object DeCircular(Object object)
{
// Set properties that cause the circular reference to null
return object
}
//first: Create a class as your view model
public class EventViewModel
{
public int Id{get;set}
public string Property1{get;set;}
public string Property2{get;set;}
}
//then from your method
[HttpGet]
public async Task<ActionResult> GetEvent()
{
var events = await db.Event.Find(x => x.ID != 0);
List<EventViewModel> model = events.Select(event => new EventViewModel(){
Id = event.Id,
Property1 = event.Property1,
Property1 = event.Property2
}).ToList();
return Json(new{ data = model }, JsonRequestBehavior.AllowGet);
}
An easier alternative to solve this problem is to return an string, and format that string to json with JavaScriptSerializer.
public string GetEntityInJson()
{
JavaScriptSerializer j = new JavaScriptSerializer();
var entityList = dataContext.Entitites.Select(x => new { ID = x.ID, AnotherAttribute = x.AnotherAttribute });
return j.Serialize(entityList );
}
It is important the "Select" part, which choose the properties you want in your view. Some object have a reference for the parent. If you do not choose the attributes, the circular reference may appear, if you just take the tables as a whole.
Do not do this:
public string GetEntityInJson()
{
JavaScriptSerializer j = new JavaScriptSerializer();
var entityList = dataContext.Entitites.toList();
return j.Serialize(entityList );
}
Do this instead if you don't want the whole table:
public string GetEntityInJson()
{
JavaScriptSerializer j = new JavaScriptSerializer();
var entityList = dataContext.Entitites.Select(x => new { ID = x.ID, AnotherAttribute = x.AnotherAttribute });
return j.Serialize(entityList );
}
This helps render a view with less data, just with the attributes you need, and makes your web run faster.

Moq Automapper service in testmethod returns null while mapping

I'm building a website in MVC 4 & using Automapper to map from domain objects to Viewmodel objects. I have injected Automapper as stated here http://rical.blogspot.in/2012/06/mocking-automapper-in-unit-testing.html
and it's working fine inside action methods while debugging, but during unit testing the action method when I inject automapper service I find that service.map is returning null. But while debugging the mapping is fine. I'm not being able to find the reason, trying for over 4 hrs. I have a domain class called Interview & its corrosponding viewmodel as InterviewModel. I have initialized mapping as CreateMap(); in automapper profile config, that has been called from global startup method. Below is the controller & action...
public class NewsAndViewsController : Controller
{
private IInterviewRepository repository;
private IMappingService mappingService;
public NewsAndViewsController(IInterviewRepository productRepository, IMappingService autoMapperMappingService)
{
repository = productRepository;
mappingService = autoMapperMappingService;
}
[HttpPost, ValidateAntiForgeryToken]
[UserId]
public ActionResult Edit(InterviewModel interView, string userId)
{
if (ModelState.IsValid)
{
var interView1 = mappingService.Map<InterviewModel, Interview>(interView);
**// THE ABOVE LINE RETURNING NULL WHILE RUNNING THE BELOW TEST, BUT NOT DURING DEBUGGING**
repository.SaveInterview(interView1);
TempData["message"] = string.Format("{0} has been saved", interView.Interviewee);
return RedirectToAction("Create");
}
return View(interView);
}
}
[TestMethod]
public void AddInterview()
{
// Arrange
var interviewRepository = new Mock<IInterviewRepository>();
var mappingService = new Mock<IMappingService>();
var im = new InterviewModel { Interviewee="sanjay", Interviewer="sanjay", Content="abc" };
mappingService.Setup(m => m.Map<Interview, InterviewModel>(It.IsAny<Interview>())).Returns(im);
var controller = new NewsAndViewsController(interviewRepository.Object, mappingService.Object);
// Act
var result = controller.Edit(im, "2") as ViewResult;
// Assert - check the method result type
Assert.IsNotInstanceOfType(result, typeof(ViewResult));
}
In your test you've got your Interview and InterviewModel classes crossed up in the mappingService.Setup() call (as an aside, I think you could use better naming conventions, or don't use var, to keep your objects clear - "im", "interview" and "interview1" don't make it easy to follow which is the model and which is the view object).
Try this:
[TestMethod]
public void AddInterview()
{
// Arrange
var interviewRepository = new Mock<IInterviewRepository>();
var mappingService = new Mock<IMappingService>();
var interview = new Interview();
var im = new InterviewModel { Interviewee="sanjay", Interviewer="sanjay", Content="abc" };
mappingService.Setup(m => m.Map<InterviewModel, Interview>(im).Returns(interview);
var controller = new NewsAndViewsController(interviewRepository.Object, mappingService.Object);
// Act
var result = controller.Edit(im, "2") as ViewResult;
// Assert - check the method result type
Assert.IsNotInstanceOfType(result, typeof(ViewResult));
}

MongoDB custom serializer implementation

I am new to MongoDB, and am trying to get the C# driver to work serializing F# classes. I have it working with the class automapper using mutable F# fields & a parameterless constructor, but really I need to retain immutability, so I started looking at implementing an IBsonSerializer to perform custom serialization. I haven't found any documentation for writing one of these so have just tried to infer from the driver source code.
I have run into a problem whereby when the Deserialize method is called on the serializer, the CurrentBsonType is set to EndOfDocument rather than the start as I am expecting. I wrote the equivalent in C# just to make sure it wasn't some F# weirdness, but the problem persists. The serialization part seems to work fine and is queryable from the shell. Here is the sample code:
class Calendar {
public string Id { get; private set; }
public DateTime[] Holidays { get; private set; }
public Calendar(string id, DateTime[] holidays) {
Id = id;
Holidays = holidays;
}
}
class CalendarSerializer : BsonBaseSerializer {
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) {
var calendar = (Calendar) value;
bsonWriter.WriteStartDocument();
bsonWriter.WriteString("_id", calendar.Id);
bsonWriter.WriteName("holidays");
var ser = new ArraySerializer<DateTime>();
ser.Serialize(bsonWriter, typeof(DateTime[]), calendar.Holidays, null);
bsonWriter.WriteEndDocument();
}
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) {
if (nominalType != typeof(Calendar) || actualType != typeof(Calendar))
throw new BsonSerializationException();
if (bsonReader.CurrentBsonType != BsonType.Document)
throw new FileFormatException();
bsonReader.ReadStartDocument();
var id = bsonReader.ReadString("_id");
var ser = new ArraySerializer<DateTime>();
var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null);
bsonReader.ReadEndDocument();
return new Calendar(id, holidays);
}
public override bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator) {
var calendar = (Calendar) document;
id = calendar.Id;
idNominalType = typeof (string);
idGenerator = new StringObjectIdGenerator();
return true;
}
public override void SetDocumentId(object document, object id) {
throw new NotImplementedException("SetDocumentId is not implemented");
}
}
This blows up with FileFormatException in Deserialize when the CurrentBsonType is not Document. I am using the latest version 1.4 of the driver source.
I figured this out in the end. I should have used bsonReader.GetCurrentBsonType() instead of bsonReader.CurrentBsonType. This reads the BsonType in from the buffer rather than just looking at the last thing there. I also fixed a subsequent bug derserializing. The updated method looks like this:
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) {
if (nominalType != typeof(Calendar) || actualType != typeof(Calendar))
throw new BsonSerializationException();
if (bsonReader.GetCurrentBsonType() != BsonType.Document)
throw new FileFormatException();
bsonReader.ReadStartDocument();
var id = bsonReader.ReadString("_id");
bsonReader.ReadName();
var ser = new ArraySerializer<DateTime>();
var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null);
bsonReader.ReadEndDocument();
return new Calendar(id, holidays);
}

Casting Object type in mvc controller

I have the folowing class and controller (mvc)
UI Model inherits DB model (ef4.0)
public class RegistrationModel : Model.User
{
[Required]
public string PasswordText { get; set; }
}
MVC controller
public ActionResult Create(RegistrationModel registrationModel)
{
try
{
Context ctx = new Context();
Model.User user = new Model.User();
user = (registrationModel as Model.User);
user.Password = System.Text.ASCIIEncoding.ASCII.GetBytes(registrationModel.PasswordText); //do encryption later on
...
ctx.Customer.Add(registrationModel as Model.User);
ctx.SaveChanges();
}
}
when i cast the registrationmodel to a user the type remains registrationmodel is there a way to cast it, without copying all its properties to a new user object?
Model.User user = new Model.User();
user.Active = registrationModel.Active;
user.Blocked = registrationModel.Blocked;
//...
....
How about using AutoMapper. Brilliant for automatically mapping data from models to view models and so on.
correct. I had the same issue. it seems that all types of casting (document in MSDN here: http://msdn.microsoft.com/en-us/library/ms173105.aspx) does not seem to work in MVC controllers.
for instance:
// IRREGULAR MVC CONTROLLERS BEHAVIOR
// implicit casting
Model.User user = registrationModelInstance // won't case to base
// explicit casting
Model.User user = (Model.User)registrationModelInstance // won't case to base
i ended up using AutoMapper (similar to User-Defined conversion per MSDN). should look like that:
Mapper.CreateMap<RegistrationModel, Model.User>();
Mapper.Map<RegistrationModel, Model.User>(registrationModelInstance);

Testing an Edit view with MVCContrib Test Helper

I am using ASP.NET MVC 3, MVCContrib, NUnit and Rhino Mocks. I have posted this but could not get an answer. People are focusing more on my coding that helping me get a decent answer to get this test to pass.
I am trying to test my Edit view. I'm not sure how to code the test for the view. It is a strongly typed view of type NewsEditViewData.
When the view loads, it gets a news item's data by ID from the news service. So in my test I created a stub of the news service:
var id = 1;
var news = new News();
newsServiceStub
.Stub(x => x.FindById(id))
.Return(news);
Now I need to map this news item to NewsEditViewData. I have a mapper (AutoMapper) that does this for me, and in my test I did the following:
newsMapperStub
.Stub(x => x.Map(news, typeof(News), typeof(NewsEditViewData)))
.Return(newsEditViewData);
I'm not sure if I am on the right track so far?
Then I have the following piece of code:
// Act
var actual = sut.Edit(id);
Don't work from my code, I want an answer following best practices. So what all do I need to check for in my assert part? Do I need to also check that a record was returned? I was thinking in the lines of something like:
actual
.AssertViewRendered()
.WithViewData<NewsEditViewData>()
.ShouldBe(newsEditViewData);
This fails. Can someone please help me rewrite this test so that it passes. I want it to check all that needs to be checked.
Here is the full test:
[Test]
public void Edit_should_render_Edit_view()
{
// Arrange
var id = 1;
var news = new News();
var newsEditViewData = new NewsEditViewData();
newsServiceStub
.Stub(x => x.FindById(id))
.Return(news);
newsMapperStub
.Stub(x => x.Map(news, typeof(News), typeof(NewsEditViewData)))
.Return(newsEditViewData);
// Act
var actual = sut.Edit(id);
// Assert
actual
.AssertViewRendered()
.WithViewData<NewsEditViewData>()
.ShouldBe(newsEditViewData);
}
UPDATE 2011-02-14:
In my NewsController I have the following:
private INewsService newsService;
private IMapper newsMapper;
public NewsController(INewsService newsService)
{
Check.Argument.IsNotNull(newsService, "newsService");
this.newsService = newsService;
newsMapper = new NewsMapper(); // TODO: Use dependency injection
}
The action method looks like this:
public ActionResult Edit(int id)
{
Check.Argument.IsNotZeroOrNegative(id, "id");
var news = newsService.FindById(id);
var newsEditViewData = (NewsEditViewData)newsMapper.Map(news, typeof(News), typeof(NewsEditViewData));
return View(newsEditViewData);
}
The error that I am getting in NUnit is:
MyProject.Web.UnitTests.Controllers.NewsControllerTests.Edit_RenderView_EditView:
MvcContrib.TestHelper.AssertionException : was MyProject.Web.Common.ViewData.NewsEditViewData but expected MyProject.Web.Common.ViewData.NewsEditViewData
You haven't shown none of your controller, repository, models. It's a question that is close to impossible to answer without this information. So lets start guessing. You have a model and a view model:
public class News { }
public class NewsEditViewData { }
I am leaving them without any properties for the purpose of this post. Then you probably have a service which is responsible for retrieving and saving your model (the view model should never appear as in/out argument of your service layer). The service should never know about the view model:
public interface INewsService
{
News FindById(int id);
void CreateNews(News news);
}
Then you probably have a mapper:
public interface IMapper
{
object Map(object source, Type sourceType, Type destinationType);
}
And finally I suppose that you have a controller that you are trying to test:
public class NewsController : Controller
{
private readonly INewsService _newsService;
private readonly IMapper _newsMapper;
public NewsController(INewsService newsService, IMapper newsMapper)
{
_newsService = newsService;
_newsMapper = newsMapper;
}
public ActionResult Edit(int id)
{
// WARNING: Meaningless action ahead as it retrieves some
// model from the service and passes this model to
// the service back again for update. In the meantime
// the model is converted to a view model using a mapper
// and passed to the view. So totally meaningless in a real
// application but let's consider for the purpose of this demonstration
var news = _newsService.FindById(id);
_newsService.CreateNews(news);
var newsEditViewData = (NewsEditViewData)_newsMapper.Map(news, typeof(News), typeof(NewsEditViewData));
return View(newsEditViewData);
}
}
OK, up until here it is you that should have provided this information.
And now I can start answering your question about the unit test which might look like this:
[Test]
public void Edit_should_fetch_news_model_from_service_given_an_id_parameter_create_news_and_pass_a_viewmodel_to_the_view()
{
// arrange
// TODO : move this part in the initialization section
// of your unit test to avoid repeating it on each method
var newsServiceStub = MockRepository.GenerateStub<INewsService>();
var newsMapperStub = MockRepository.GenerateStub<IMapper>();
var sut = new NewsController(newsServiceStub, newsMapperStub);
new TestControllerBuilder().InitializeController(sut);
var news = new News();
var id = 123;
var newsEditViewData = new NewsEditViewData();
newsServiceStub
.Stub(x => x.FindById(id))
.Return(news);
newsMapperStub
.Stub(x => x.Map(news, typeof(News), typeof(NewsEditViewData)))
.Return(newsEditViewData);
// act
var actual = sut.Edit(id);
// assert
actual
.AssertViewRendered()
.WithViewData<NewsEditViewData>()
.ShouldBe(newsEditViewData);
newsServiceStub.AssertWasCalled(x => x.CreateNews(news));
}

Resources