Testing property set with a List in Rhino Mocks - list

I feel like I have lost my mind because I am sure I have done this before. Hopefully one of you can point me in the right direction.
Essentially I have an view that I want to test that the presenter is correctly setting the property with a list of objects. Example:
public ComplexDto{
public string name{get;set;}
public string description{get;set;}
}
public interface ITestView{
IList<ComplexDto> dto{get;set;}
}
Within the Presenter it sets a list like:
...
var dtos = new List<ComplexDto>();
dtos.add(new ComplexDto(){name="test name", description="this is some description"}
view.dto = dtos;
...
I need to test that that contents of the list of the dto work.
I have tried GetArgumentsForCallsMadeOn but I think this does not work with properties.
Thanks for any help!

EDIT
This should do it:
var view = MockRepository.GenerateMock<ITestView>();
var dtos = new List<ComplexDto>();
dtos.Add(new ComplexDto() {name = "test name", description = "this is some description"});
List<ComplexDto> passedIn;
view.Expect(v => v.dto).SetPropertyWithArgument(dtos).WhenCalled(mi => passedIn = (List<ComplexDto>) mi.Arguments[0]);
view.dto = dtos;
view.VerifyAllExpectations();

Related

Error when attempting to run my XUnit Tests

I wrote a few tests in XUnit to test my data access layer. I instantiated my DAL objects & configs the same way I would if I were using it in the actual web application(this is configured to run against a dev environment for testing purposes), however XUnit throws an error:
Message: The following constructor parameters did not have matching fixture data: IConfiguration config, IMediaDataAccess media
I'm a bit new to XUnit, so unsure what the problem is. Normally ASP.NET would inject instances of IConfiguration and IMediaDataAccess for me, but that doesn't seem to be the case here.
My Test class & a sample test case:
public class DataAccessLayerTests
{
public IConfiguration Config { get; set; }
private IMediaDataAccess mediaData;
public IMediaDataAccess MediaData { get => mediaData; set => mediaData = value; }
public DataAccessLayerTests(IConfiguration config, IMediaDataAccess media)
{
this.MediaData = media;
this.Config = config;
}
public void GetAllMediaAsync_MediaListIsReturned()
{
List<Media> testData = mediaData.GetAllMedia().Result;
Assert.IsType<List<Media>>(testData);
}
}
The test(s) all fail due to the following error: Message: The following constructor parameters did not have matching fixture data: IConfiguration config, IMediaDataAccess media
For anyone else having this problem, Alexey's comment is correct. You need to download a mocking framework (like Moq) and use it to mock up the dependencies your code is expecting. For example, below is one of my fixed unit tests:
public void IndexDataModel_ShouldDisplayMedia()
{
var mockLogger = new Mock<ILogger<IndexModel>>();
var mockDataAccess = new Mock<IMediaDataAccess>();
mockDataAccess.Setup(media => media.GetAllMedia()).ReturnsAsync(GetTestMedia());
IndexModel indexController = new IndexModel(mockDataAccess.Object, mockLogger.Object);
var result = indexController.OnGet();
var viewResult = Assert.IsType<PageResult>(result);
var model = Assert.IsAssignableFrom<IEnumerable<Media>>(
indexController.mediaList);
}
The trick is you need to mock up anything that you normally depend on getting injected into your constructor, in my case this was:
var mockLogger = new Mock<ILogger<IndexModel>>();
var mockDataAccess = new Mock<IMediaDataAccess>();
My constructor takes both an ILogger and an IMediaDataAccess, so I needed to mock those. Additionally, the other code is there to provide dummy return values when your mocked dependencies are used by the test. This is done with the .Setup line of code. All this does(I think) is when GetAllMedia() is called, the mock object returns the contents of GetTestMedia() instead of needing to make the actual calls. Just make sure whatever function you write has the same return type as the real function. For reference, this is my GetTestMedia() function:
private List<Media> GetTestMedia()
{
var listMedia = new List<Media>();
Media testMedia = new Media
{
Description = "TestDesc",
Genre = "TestGenre",
Name = "TestName",
Rating = MediaRating.Excellent,
Type = MediaType.Movie,
Id = 1
};
listMedia.Add(testMedia);
Media testMedia2 = new Media
{
Description = "TestDesc2",
Genre = "TestGenre2",
Name = "TestName2",
Rating = MediaRating.Poor,
Type = MediaType.Music,
Id = 2
};
listMedia.Add(testMedia2);
return listMedia;
}

Testing Using NUnit and Moq: use case

I have a business class that manage a USER entity.
In this class I have a method to return a single user by id:
public Utente GetUser(int id)
{
var utente = _userDataManager.GetUserById(id);
return _mapper.Map<Utente>(utente);
}
_userDataManager is an interface, IUSERDATAMANAGER, and it has implemented with a DAL class; GetUserById return a user or null (search made with EF6).
_mapper is a IMAPPER interface (automapper).
The method return is the mapped object.
I have two question:
Does it make sense to test this method?
Should I mock both the object?
A black-boxed example will be appreciated.
Does it make sense to test this method?
If it is worth writing the code it is worth testing the code.
Should I mock both the object?
When testing a subject under test, you mock the dependencies that would allow the test to be exercised to completion.
For example
public void GetUser_Should_Return_Utente() {
//Arrange
var userId = 2;
var user = new User {
UserId = userId,
//... other properties
};
var userDataManagerMock = new Mock<IUserDataManager>();
userDataManagerMock.Setup(_ => _.GetUserById(userId)).Returns(user);
var expected = new Utente {
Id = user.Id,
//...other properties
}
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(_ => _.Map<Utente>(It.IsAny<object>())).Returns(expected);
var subject = new MyBusinessClass(userDataManagerMock.Object, mapperMock.Object);
//Act
var actual = subject.GetUser(userId);
//Assert
Assert.Equal(expected, actual);
}
In the above code the user data manager and the mapper a mocked and injected into the subject when testing the GetUser method.
This is an isolated unit test of the above method and shows the the current implementation of that method will flow to completion provided the dependencies perform as expected during invocation.

Asp. NET MVC 4.5 - How to Unit Test Actions?

In Asp.net MVC 4.5 , using Microsoft.VisualStudio.TestTools.UnitTesting.
is there a way to really unit test an ActionResult? All documentation I have seen only tests the view name!
Assert.AreEqual("Action Method", result.ViewName);
Well, I want to have a really test. How can I test the response of the controller-action ?
Given something basic along the lines of:
public ActionResult Display(string productCode)
{
var model = new ProductModel(productCode);
if (model.NotFound)
{
return this.RedirectToRoute("NotFound");
}
return this.View("Product", model);
}
Instead of something that asserts like Assert.AreEqual("Action Method", result.ViewName); (which can be a valid test.
You have many options including...
Looking at the model type
[TestMethod]
public void Display_WhenPassedValidProductCode_CreatesModel()
{
using (var controller = this.CreateController())
{
// Arrange Mocks on controller, e.g. a Service or Repository
// Act
var result = controller.Display(string.Empty) as ViewResult;
var model = (ProductModel)result.Model;
Assert.IsInstanceOfType(model, typeof(ProductModel));
}
}
Looking at the model population process
[TestMethod]
public void Display_WhenPassedValidProductCode_PopulatesModel()
{
using (var controller = this.CreateController())
{
const string ProductCode = "123465";
// Arrange Mocks on controller, e.g. a Service or Repository
// Act
var result = controller.Display(ProductCode) as ViewResult;
var model = (ProductModel)result.Model;
Assert.AreEqual(ProductCode, model.ProductCode);
}
}
Looking at the type of action result
[TestMethod]
public void Display_WhenNotFound_Redirects()
{
using (var controller = this.CreateController())
{
const string ProductCode = "789000";
// Arrange Mocks on controller, e.g. a Service or Repository
// Act
var result = controller.Display(ProductCode) as RedirectToRouteResult;
Assert.IsNotNull(result); // An "as" cast will be null if the type does not match
}
}
Basically you can test pretty much anything, pick an example on your code base and try and test it. If you get stuck construct a decent question and post it here.

How do I mock the DB models?

I am trying to test a repository and so need to mock the Model Container. Really all I need is to be able to set the Blogs returned to GetBlogs() in the BlogRepository. The repository code is:
private BlogWebsiteModelContainer context;
public BlogRepository(BlogWebsiteModelContainer context)
{
this.context = context;
}
public IEnumerable<Blog> GetBlogs()
{
return context.Blogs;
}
So I want to be able to set what context.Blogs is. I am using Moq and have tried the following:
var mockBlogSet = new Mock<DbSet<Blog>>();
context.Setup(m => m.Blogs).Returns(mockBlogSet.Object);
blogRepo = new BlogRepository(context.Object);
But I get this error message when I debug:
Invalid setup on a non-virtual (overridable in VB) member: m => m.Blogs
Any help greatly appreciated.
Create an interface for your BlogWebsiteModelContainer, then mock the interface. Also instead of defining Blogs on the interface as DbSet<Blog> define it as IQuerayable<Blog>
You can then create a List and use the .AsQueryable extension:
var contextMock = new Mock<IBlogWebsetModelContainer>();
var mockBlogSet = new List<Blog>();
contextMock.Setup(m => m.Blogs).Returns(mockBlogSet.AsQueryable());
blogRepo = new BlogRepository(contextMock.Object);
I found the answer at this link http://msdn.microsoft.com/en-us/data/dn314429.aspx. And so my code became the following:
List<Blog> blogs = new List<Blog>
{
new Blog() { Id = 1 },
new Blog() { Id = 2 },
new Blog() { Id = 3 },
};
var data = blogs.AsQueryable();
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
var mockContext = new Mock<BlogWebsiteModelContainer>();
mockContext.Setup(c => c.Blogs).Returns(mockSet.Object);
blogRepo = new BlogRepository(mockContext.Object);
Then I had to go into my BlogWebsiteModelContainer class and change:
public DbSet<Blog> Blogs { get; set; }
to
public virtual DbSet<Blog> Blogs { get; set; }
Just adding the virtual in. And it all worked.
Quick note: reason for creating the list first and then making it .AsQueryable() was so in my code I had the original blog list separate so I could compare it in my tests.

MVC 3 Unit Test - Get Actual Response Data

All,
I'm developing and unit testing an interactive voice application using ASP.NET MVC 3 whose controllers return Views containing VoiceXML. I'd like to create unit tests that capture the actual VoiceXML output so I can schema-validate it.
My reading and testing have taken me to Scott H's FakeHttpContext that uses Moq, as well as several responses here. Everything compiles correctly, and I'm trying to do something like the following:
[TestMethod]
public void WelcomeTest1()
{
EmergencyController controller = new EmergencyController();
controller.ControllerContext = new ControllerContext(MvcMockHelpers.FakeHttpContext("~/Emergency/Welcome"), new RouteData(), controller);
ViewResult result = (controller.Welcome()) as ViewResult;
.
.
Assert.IsTrue(controller.ControllerContext.HttpContext.Response.OutputStream.Length > 0);
// assert schema validation on the output here
}
However, stepping through this, I can see that the Welcome view being called, but I'm looking for something in the Response.Output and not finding anything. The mock is set up as follows, in hope that setting CallBase to true would actually write something out. I found some code that I added to the FakeHttpContext constructor that supposedly invokes a StringWriter, but to no avail:
public static HttpContextBase FakeHttpContext()
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>() { CallBase = true };
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session.Object);
context.Setup(ctx => ctx.Server).Returns(server.Object);
response.Setup(r => r.OutputStream).Returns(new MemoryStream());
response.Setup(r => r.Headers).Returns(new NameValueCollection());
var writer = new StringWriter();
var wr = new SimpleWorkerRequest("", "", "", "", writer);
HttpContext.Current = new HttpContext(wr);
return context.Object;
}
I'm sure I'm missing something obvious, but I'm stumped right now.
Thanks
Jim Stanley
Blackboard Connect
The result doesn't get populated in the ViewResult. In other words, the view isn't rendered by you calling return View() in your controller, rather mvc takes the viewresult and renders it at a later time in the request-sycle. What you need to do is to create a render-function for ViewResults, like this one:
using System;
using System.IO;
using System.Web.Mvc;
namespace CoPrice.Helpers
{
public static class ViewRendrer
{
public static string ToHtml(this ViewResult result, Controller controller)
{
controller.ViewData.Model = result.Model;
try
{
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, result.ViewName);
ViewContext context = new ViewContext(controller.ControllerContext, viewResult.View, result.ViewData, result.TempData, sw);
viewResult.View.Render(context, sw);
return sw.GetStringBuilder().ToString();
}
}
catch (Exception e)
{
return e.ToString();
}
}
}
}
Then you can do result.ToHtml(controller) to get the actual data (this works for RazorViews only I think, though I'm not sure, that's what I've used it for at least).