Mock DbQuery to use FromSql from unit tests - unit-testing

I am using EF Core in a projet to get stored procedure calling. In my context i have the following :
public class MyContext : DbContext
{
public DbQuery<User> UserQuery { get; set; }
public MyContext(DbContextOptions<MyContext> options) : base(options) { }
}
And i call the stored procedure like this :
public virtual async Task<User> GetUserAsync(string name)
{
return await MyContext.Query<User>()
.FromSql($"EXEC [dbo].[GetUser], #Login = {name}")
.FirstOrDefaultAsync();
}
Code is working fine. I need to test this method in unit tests, i'm using InMemoryDatabase to mock my context MyContext like this :
[Fact]
public async Task GetUserAsync_should_return_first_user_with_login_and_password_if_exists()
{
// Arrange
var users = new List<User>
{
new User()
{
Login = "test#outlook.fr",
Password = "pass1",
},
};
var options = new DbContextOptionsBuilder<MyContext>()
.UseInMemoryDatabase(databaseName: "BddName")
.Options;
var context = new MyContext(options);
var loginProvider = A.Fake<LoginProvider>(opts => opts.WithArgumentsForConstructor(() => new LoginProvider(context)));
// Act
// Assert
context.Dispose();
}
And i have no idea how can i set my list into the result of the stored procedure called from DbQuery. I tried to follow this article : https://nodogmablog.bryanhogan.net/2017/11/unit-testing-entity-framework-core-stored-procedures/ but it works for DbSet only and not DbQuery.
I need some advices for this case.
Thanks in advance.

The link in the OP does apply to the DbQuery type as well, as you're mocking the provider. Both DbSet and DbQuery work in the same way in this regard.
See https://stackoverflow.com/a/56940311/2975810 for a previous answer on the topic.

Related

Unit testing web api controller with role based authorization [duplicate]

I have an ASP.NET MVC Core application that I am writing unit tests for. One of the action methods uses User name for some functionality:
SettingsViewModel svm = _context.MySettings(User.Identity.Name);
which obviously fails in the unit test. I looked around and all suggestions are from .NET 4.5 to mock HttpContext. I am sure there is a better way to do that. I tried to inject IPrincipal, but it threw an error; and I even tried this (out of desperation, I suppose):
public IActionResult Index(IPrincipal principal = null) {
IPrincipal user = principal ?? User;
SettingsViewModel svm = _context.MySettings(user.Identity.Name);
return View(svm);
}
but this threw an error as well.
Couldn't find anything in the docs either...
The controller’s User is accessed through the HttpContext of the controller. The latter is stored within the ControllerContext.
The easiest way to set the user is by assigning a different HttpContext with a constructed user. We can use DefaultHttpContext for this purpose, that way we don’t have to mock everything. Then we just use that HttpContext within a controller context and pass that to the controller instance:
var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, "example name"),
new Claim(ClaimTypes.NameIdentifier, "1"),
new Claim("custom-claim", "example claim value"),
}, "mock"));
var controller = new SomeController(dependencies…);
controller.ControllerContext = new ControllerContext()
{
HttpContext = new DefaultHttpContext() { User = user }
};
When creating your own ClaimsIdentity, make sure to pass an explicit authenticationType to the constructor. This makes sure that IsAuthenticated will work correctly (in case you use that in your code to determine whether a user is authenticated).
In previous versions you could have set User directly on the controller, which made for some very easy unit tests.
If you look at the source code for ControllerBase you will notice that the User is extracted from HttpContext.
/// <summary>
/// Gets the <see cref="ClaimsPrincipal"/> for user associated with the executing action.
/// </summary>
public ClaimsPrincipal User => HttpContext?.User;
and the controller accesses the HttpContext via ControllerContext
/// <summary>
/// Gets the <see cref="Http.HttpContext"/> for the executing action.
/// </summary>
public HttpContext HttpContext => ControllerContext.HttpContext;
You will notice that these two are read only properties. The good news is that ControllerContext property allows for setting it's value so that will be your way in.
So the target is to get at that object. In Core HttpContext is abstract so it is a lot easier to mock.
Assuming a controller like
public class MyController : Controller {
IMyContext _context;
public MyController(IMyContext context) {
_context = context;
}
public IActionResult Index() {
SettingsViewModel svm = _context.MySettings(User.Identity.Name);
return View(svm);
}
//...other code removed for brevity
}
Using Moq, a test could look like this
public void Given_User_Index_Should_Return_ViewResult_With_Model() {
//Arrange
var username = "FakeUserName";
var identity = new GenericIdentity(username, "");
var mockPrincipal = new Mock<ClaimsPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(identity);
mockPrincipal.Setup(x => x.IsInRole(It.IsAny<string>())).Returns(true);
var mockHttpContext = new Mock<HttpContext>();
mockHttpContext.Setup(m => m.User).Returns(mockPrincipal.Object);
var model = new SettingsViewModel() {
//...other code removed for brevity
};
var mockContext = new Mock<IMyContext>();
mockContext.Setup(m => m.MySettings(username)).Returns(model);
var controller = new MyController(mockContext.Object) {
ControllerContext = new ControllerContext {
HttpContext = mockHttpContext.Object
}
};
//Act
var viewResult = controller.Index() as ViewResult;
//Assert
Assert.IsNotNull(viewResult);
Assert.IsNotNull(viewResult.Model);
Assert.AreEqual(model, viewResult.Model);
}
There is also the possibility to use the existing classes, and mock only when needed.
var user = new Mock<ClaimsPrincipal>();
_controller.ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext
{
User = user.Object
}
};
In my case, I needed to make use of Request.HttpContext.User.Identity.IsAuthenticated, Request.HttpContext.User.Identity.Name and some business logic sitting outside of the controller. I was able to use a combination of Nkosi's, Calin's and Poke's answer for this:
var identity = new Mock<IIdentity>();
identity.SetupGet(i => i.IsAuthenticated).Returns(true);
identity.SetupGet(i => i.Name).Returns("FakeUserName");
var mockPrincipal = new Mock<ClaimsPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(identity.Object);
var mockAuthHandler = new Mock<ICustomAuthorizationHandler>();
mockAuthHandler.Setup(x => x.CustomAuth(It.IsAny<ClaimsPrincipal>(), ...)).Returns(true).Verifiable();
var controller = new MyController(...);
var mockHttpContext = new Mock<HttpContext>();
mockHttpContext.Setup(m => m.User).Returns(mockPrincipal.Object);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext()
{
User = mockPrincipal.Object
};
var result = controller.Get() as OkObjectResult;
//Assert results
mockAuthHandler.Verify();
I want to hit my Controllers directly and just use DI like AutoFac. To do this I first registering ContextController.
var identity = new GenericIdentity("Test User");
var httpContext = new DefaultHttpContext()
{
User = new GenericPrincipal(identity, null)
};
var context = new ControllerContext { HttpContext = httpContext};
builder.RegisterInstance(context);
Next I enable property injection when I register the Controllers.
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Controller")).PropertiesAutowired();
Then User.Identity.Name is populated, and I do not need to do anything special when calling a method on my Controller.
public async Task<ActionResult<IEnumerable<Employee>>> Get()
{
var requestedBy = User.Identity?.Name;
..................
I would look to implement an Abstract Factory Pattern.
Create an interface for a factory specifically for providing user names.
Then provide concrete classes, one which provides User.Identity.Name, and one that provides some other hard coded value that works for your tests.
You can then use the appropriate concrete class depending on production versus test code. Perhaps looking to pass the factory in as a parameter, or switching to the correct factory based on some configuration value.
interface IUserNameFactory
{
string BuildUserName();
}
class ProductionFactory : IUserNameFactory
{
public BuildUserName() { return User.Identity.Name; }
}
class MockFactory : IUserNameFactory
{
public BuildUserName() { return "James"; }
}
IUserNameFactory factory;
if(inProductionMode)
{
factory = new ProductionFactory();
}
else
{
factory = new MockFactory();
}
SettingsViewModel svm = _context.MySettings(factory.BuildUserName());
I got a brownfield .net 4.8 project that I needed to convert to .net 5.0 and I wanted to keep as much of the original code as possible, including the unit-/integration tests. The test for Controllers relied on the Context a lot so I created this Extension method to enable setting tokens, claims and headers:
public static void AddContextMock(
this ControllerBase controller,
IEnumerable<(string key, string value)> claims = null,
IEnumerable<(string key, string value)> tokens = null,
IEnumerable<(string key, string value)> headers = null)
{
HttpContext mockContext = new DefaultHttpContext();
if(claims != null)
{
mockContext.User = SetupClaims(claims);
}
if(tokens != null)
{
mockContext.RequestServices = SetupTokens(tokens);
}
if(headers != null)
{
SetupHeaders(mockContext, headers);
}
controller.ControllerContext = new ControllerContext()
{
HttpContext = mockContext
};
}
private static void SetupHeaders(HttpContext mockContext, IEnumerable<(string key, string value)> headers)
{
foreach(var header in headers)
{
mockContext.Request.Headers.Add(header.key, header.value);
}
}
private static ClaimsPrincipal SetupClaims(IEnumerable<(string key, string value)> claimValues)
{
var claims = claimValues.Select(c => new Claim(c.key, c.value));
return new ClaimsPrincipal(new ClaimsIdentity(claims, "mock"));
}
private static IServiceProvider SetupTokens(IEnumerable<(string key, string value)> tokenValues)
{
var mockServiceProvider = new Mock<IServiceProvider>();
var authenticationServiceMock = new Mock<IAuthenticationService>();
var authResult = AuthenticateResult.Success(
new AuthenticationTicket(new ClaimsPrincipal(), null));
var tokens = tokenValues.Select(t => new AuthenticationToken { Name = t.key, Value = t.value });
authResult.Properties.StoreTokens(tokens);
authenticationServiceMock
.Setup(x => x.AuthenticateAsync(It.IsAny<HttpContext>(), null))
.ReturnsAsync(authResult);
mockServiceProvider.Setup(_ => _.GetService(typeof(IAuthenticationService))).Returns(authenticationServiceMock.Object);
return mockServiceProvider.Object;
}
This uses Moq but can be adapted to other mocking frameworks. The authentication type is hardcoded to "mock" since I rely on default authentication but this could be supplied as well.
It is used as such:
_controllerUnderTest.AddContextMock(
claims: new[]
{
(ClaimTypes.Name, "UserName"),
(ClaimTypes.MobilePhone, "1234"),
},
tokens: new[]
{
("access_token", "accessTokenValue")
},
headers: new[]
{
("header", "headerValue")
});
If you're using Razor pages and want to override the claims:
[SetUp]
public void Setup()
{
var user = new ClaimsPrincipal(new ClaimsIdentity(
new Claim[] {
new("dateofbirth", "2000-10-10"),
new("surname", "Smith") },
"mock"));
_razorModel = new RazorModel()
{
PageContext = new PageContext
{
HttpContext = new DefaultHttpContext() { User = user }
}
};
}

Unit testing view model that uses SelectMany to call an async method in ReactiveUI

I am new to ReactiveUI and trying to test a view model that looks like this:
public interface IService
{
Task<SessionModel> GetData(string id);
}
/// Provides a group of schedulers available to be used
public interface ISchedulers
{
IScheduler Default { get; }
IScheduler Dispatcher { get; }
}
public class MyVm : ReactiveObject
{
IService service;
public MyVm(ISchedulers schedulers, IService service)
{
this.service = service;
this.session = this.WhenAnyValue(x => x.SessionId)
.SelectMany(SearchSession)
.ObserveOn(schedulers.Default)
.ToProperty(this, x => x.Session);
}
private async Task<SessionModel> SearchSession(string id)
{
return await this.service.GetData(id);
}
private string sessionId;
public string SessionId
{
get => sessionId;
set => this.RaiseAndSetIfChanged(ref sessionId, value);
}
readonly ObservableAsPropertyHelper<SessionModel> session;
public SessionModel Session
{
get { return session.Value; }
}
}
public class SessionModel { }
I'm mocking the service call to return dummy data, but not sure what I need to do with a TestScheduler in order to get the SelectMany to work.
Here's a test class that shows how i would create a test for the view model. The goal is to eventually be able to check that the model got set:
[TestClass]
public class MyVmTests
{
[TestMethod]
public void CreateClass
{
var subject = new MyVm(/*pass in mocks*/);
subject.SessionId="test";
Assert.IsNotNull(subject.Session);
}
}
I don't think using TestScheduler is necessary. The following passes for me (using Moq):
var mockSchedulers = new Mock<ISchedulers>();
mockSchedulers.Setup(s => s.Default).Returns(Scheduler.Immediate);
var id = "123";
var mockService = new Mock<IService>();
var returnSession = new SessionModel();
mockService.Setup(s => s.GetData(It.Is<string>(i => i == id)))
.ReturnsAsync(returnSession);
var target = new MyVm(mockSchedulers.Object, mockService.Object);
target.SessionId = id;
Assert.IsNotNull(target.Session);
Assert.AreEqual(returnSession, target.Session);
TestScheduler is best when you're trying to test something with time (like a Delay, proving that the Delay actually happened). You're not really doing that here.

How to unit test Service Stacks Redis Client with Moq

I'm trying to understand how can I mock the IRedisClientsManager so that I can unit test the Handle Method below using Moq.
Cheers
public class PropertyCommandHandler : ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult>
{
private readonly IRedisClientsManager _manager;
public PropertyCommandHandler(IRedisClientsManager manager)
{
this._manager = manager;
}
public PropertyCommandResult Handle(PropertySaveRequest request)
{
request.Property.OwnerId.ValidateArgumentRange();
using (var client =_manager.GetClient())
{
var propertyClient = client.As<Model.Property>();
var propertyKey = string.Format("property:{0}", request.Property.OwnerId);
propertyClient.SetEntry(propertyKey, request.Property);
client.AddItemToSet("property", request.Property.OwnerId.ToString());
}
return new PropertyCommandResult() {Success = true};
}
}
Which I call from the service like so
public class PropertyService : Service, IPropertyService
{
private readonly ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult> _commandHandler;
public PropertyService(ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult> commandHandler)
{
this._commandHandler = commandHandler;
}
public object Post(PropertySaveRequest request)
{
if (request.Property == null)
throw new HttpError(HttpStatusCode.BadRequest, "Property cannot be null");
var command = _commandHandler.Handle(request);
return command;
}
}
so far this has been the approach - not sure if on right track
[Test]
public void TestMethod1()
{
//arrange
_container = new WindsorContainer()
.Install(new PropertyInstaller());
var mock = new Mock<IRedisClientsManager>();
var instance = new Mock<RedisClient>();
mock.Setup(t => t.GetClient()).Returns(instance);
// cannot resolve method error on instance
// stuck ...
var service = _container.Resolve<IPropertyService>(mock);
}
In short, since RedisClient implements IRedisClient, did you try to create the mock using the interface?
var instance = new Mock<IRedisClient>();
why are you using a real container for your unit test?
You should use an auto-mocking container or simply (since you are already taking care of the mock manually) create a real instance of your test target supplying mocks as dependencies
var target= new PropertyCommandHandler(mock);
BTW IMHO a "command handler" that returns a value sounds like a smell...

CommonDomain - how to unit test aggregate root

I have a small system that uses Jonathan Oliver's CommonDomain and EventStore.
How can I unit test my aggregate roots in order to verify that correct events are raised?
Consider following aggregate root:
public class Subscriber : AggregateBase
{
private Subscriber(Guid id)
{
this.Id = id;
}
private Subscriber(Guid id, string email, DateTimeOffset registeredDate)
: this(id)
{
this.RaiseEvent(new NewSubscriberRegistered(this.Id, email, registeredDate));
}
public string Email{ get; private set; }
public DateTimeOffset RegisteredDate { get; private set; }
public static Subscriber Create(Guid id, string email, DateTimeOffset registeredDate)
{
return new Subscriber(id, email, registeredDate);
}
private void Apply(NewSubscriberRegistered #event)
{
this.Email = #event.Email;
this.RegisteredDate = #event.RegisteredDate;
}
}
I would like to write a following test:
// Arrange
var id = Guid.NewGuid();
var email = "test#thelightfull.com";
var registeredDate = DateTimeOffset.Now;
// Act
var subscriber = Subscriber.Create(id, email, registeredDate);
// Assert
var eventsRaised = subscriber.GetEvents(); <---- How to get the events?
// Assert that NewSubscriberRegistered event was raised with valid data
I could set up whole EventStore with memory persistence and synchronous dispatcher, hook up mock event handler and store any published events for verification, but it seems a bit of overkill.
There is an interface IRouteEvents in CommonDomain. Looks like I could mock it to get the events directly from AggregateBase but how would I actually pass it to my Subscriber class? I don't want to 'pollute' my domian with testing-related code.
I've found out that AggregateBase explicitly implements IAggregate interface, which exposes ICollection GetUncommittedEvents(); method.
So the unit test looks like that:
var eventsRaised = ((IAggregate)subscriber).GetUncommittedEvents();
and no dependency on EventStore is required.
I just pushed up NEventStoreExample with code I gathered in various places (StackOverflow, Documently, Greg Young's skillcast).
It's a very basic implementation of NEventStore that uses CommonDomain to rebuild aggregate state and an EventSpecification base test class to test aggregate behaviour.
Here is a fairly simple test fixture that uses NUnit and ApprovalTests to test CommonDomain aggregate roots . (ApprovalTests is not required - just kinda makes life simple).
The assumption is that
1) the fixture is instantiated with an aggregate (perhaps already set in a certain state) along with a series of 'given' events to be applied.
2) the test will then invoke a specific command handler as part of the TestCommand method - current expectation is a Func that returns the command that is handled
3) the aggregate snapshot, commands, and events all contain 'rich' ToString methods
The TestCommand method then compares the expected with the approved interactions within the aggregate.
public class DomainTestFixture<T>
where T : AggregateBase
{
private readonly T _agg;
private readonly StringBuilder _outputSb = new StringBuilder();
public DomainTestFixture(T agg, List<object> giveEvents)
{
_agg = agg;
_outputSb.AppendLine(string.Format("Given a {0}:", agg.GetType().Name));
giveEvents.ForEach(x => ((IAggregate) _agg).ApplyEvent(x));
_outputSb.AppendLine(
giveEvents.Count == 0
? string.Format("with no previously applied events.")
: string.Format("with previously applied events:")
);
giveEvents.ForEach(x => _outputSb.AppendLine(string.Format(" - {0}", x)));
((IAggregate) _agg).ClearUncommittedEvents();
var snapshot = ((IAggregate) _agg).GetSnapshot();
_outputSb.AppendLine(string.Format("which results in the state: {0}", snapshot));
}
public void TestCommand(Func<T, object> action)
{
var cmd = action.Invoke(_agg);
_outputSb.AppendLine(string.Format("When handling the command: {0}", cmd));
_outputSb.AppendLine(string.Format("Then the {0} reacts ", _agg.GetType().Name));
var raisedEvents = ((IAggregate) _agg).GetUncommittedEvents().Cast<object>().ToList();
_outputSb.AppendLine(
raisedEvents.Count == 0
? string.Format("with no raised events")
: string.Format("with the following raised events:")
);
raisedEvents.ForEach(x => _outputSb.AppendLine(string.Format(" - {0}", x)));
var snapshot = ((IAggregate) _agg).GetSnapshot();
var typ = snapshot.GetType();
_outputSb.AppendLine(string.Format("and results in the state: {0}", snapshot));
Approvals.Verify(_outputSb.ToString());
Assert.Pass(_outputSb.ToString());
}
}
and an example usage
[Test]
public void Test_Some_Aggregate_Handle_Command()
{
var aggId = Guid.Empty;
var tester = new DomainTestFixture<PartAggregate>(
new PartAggregate(aggId, null),
new List<object>()
{
new PartOrdered(),
new PartReceived()
}
);
tester.TestCommand(
(agg) =>
{
var cmd = new RejectPart();
agg.Handle(cmd);
return cmd;
});
}

How To Write Unit Test For Method Returning JsonResult With RenderPartialViewToString?

If you look at the example at this link:
http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/
How would one write a unit test for the JsonAdd method? I have a similar situation in my own code, but the RenderPartialViewToString errors when calling:
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView
I've tried different ways of trying to stub that call to no avail. Any help appreciated. Thanks.
I had a lot of trouble to make unit test working with RenderPartialViewToString.
I succeeded by doing 2 things.
I had to mock the view engine and the controller context.
Here the code :
public ViewEngineResult SetupViewContent(string viewName, string viewHtmlContent)
{
var mockedViewEngine = new Mock<IViewEngine>();
var resultView = new Mock<IView>();
resultView.Setup(x => x.Render(It.IsAny<ViewContext>(), It.IsAny<TextWriter>()))
.Callback<ViewContext, TextWriter>((v, t) =>
{
t.Write(viewHtmlContent);
});
var viewEngineResult = new ViewEngineResult(resultView.Object, mockedViewEngine.Object);
mockedViewEngine.Setup(x => x.FindPartialView(It.IsAny<ControllerContext>(), viewName, It.IsAny<bool>()))
.Returns<ControllerContext, string, bool>((controller, view, useCache) =>
{
return viewEngineResult;
});
mockedViewEngine.Setup(x => x.FindView(It.IsAny<ControllerContext>(), viewName, It.IsAny<string>(), It.IsAny<bool>()))
.Returns<ControllerContext, string, string, bool>((controller, view, masterName, useCache) =>
{
return viewEngineResult;
});
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(mockedViewEngine.Object);
return viewEngineResult;
}
public void SetContext(ref PointCollecteLivraisonController controller)
{
SetupViewContent("MyViewName", "TheViewContent");
var httpContextBase = new Mock<HttpContextBase>();
var httpRequestBase = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var routes = new RouteCollection();
RouteConfigurator.RegisterRoutes(routes);
var routeData = new RouteData();
routeData.Values.Add("controller", "PointCollecteLivraison");
routeData.Values.Add("action", "RechercheJson");
httpContextBase.Setup(x => x.Response).Returns(response.Object);
httpContextBase.Setup(x => x.Request).Returns(httpRequestBase.Object);
httpContextBase.Setup(x => x.Session).Returns(session.Object);
session.Setup(x => x["somesessionkey"]).Returns("value");
httpRequestBase.Setup(x => x.Form).Returns(new NameValueCollection());
controller.ControllerContext = new ControllerContext(httpContextBase.Object, routeData, controller);
controller.Url = new UrlHelper(new RequestContext(controller.HttpContext, routeData), routes);
}
And that is the way i use it all :
PointCollecteLivraisonController controller = new PointCollecteLivraisonController();
SetContext(ref controller);
Here are my sources :
View engine mocking : http://thoai-nguyen.blogspot.fr/2011/04/test-mock-mvc-view-engine.html
Controller context mocking : ASP.NET MVC - Unit testing RenderPartialViewToString() with Moq framework?
Hope this help.
Since ViewEninges is a static class, you can't mock it with RhinoMocks. I think your best bet is to create a "partial view renderer" interface. An interface is mockable so you'll be able to stub out the complexity of rendering the view. Here's some quick pseudo-code thrown together.
First, define the partial view renderer interface:
public interface IRenderPartialView
{
string Render(string viewName, object model);
}
Then, change your base class' RenderPartialViewToString to be the implementation of IRenderPartialView.Render:
public abstract class BaseController : Controller, IRenderPartialView
{
...
public string Render(string viewName, object model)
{
// same code as RenderPartialViewToString
}
}
Now we need to change your controller constructors so we can inject an IRenderPartialView during testing -- but use the base class one during production. We can accomplish this by using a pair of constructors:
public class YourController : BaseController
{
private IRenderPartialView partialRenderer;
public YourController()
{
SetRenderer(this);
}
public YourController(IRenderPartialView partialRenderer)
{
SetRenderer(partialRenderer);
}
private void SetRenderer(IRenderPartialView partialRenderer)
{
this.partialRenderer = this;
}
}
Now, JsonAdd can call the partial view renderer:
public JsonResult JsonAdd(AddPersonViewModel AddPersonModel)
{
...
return Json(new
{
Success = true,
Message = "The person has been added!",
PartialViewHtml = partialRenderer.Render("PersonList", new PersonListViewModel {PersonList = _personList})
});
}
So, during testing, you'll mock out an IRenderPartialView and send that to the constructor that accepts an IRenderPartialView. During production, when ASP.NET MVC calls your default constructor, it will use the controller as the renderer (which has the implementation of IRenderPartialView.Render inside the base class).