I have the following controller action method.
[HttpPost]
public ActionResult CreateProvider(Provider provider)
{
try
{
int providerCreationSuccessful = _repository.CreateProvider(provider);
if (providerCreationSuccessful == 2)
TempData["userIntimation"] = "Provider Registered Successfully";
//return RedirectToAction("ShowTheListOfProviders");
}
catch (Exception Ex)
{
_logger.Error(Ex.Message);
return View("Error");
}
return Json(new { url = Url.Action("ShowTheListOfProviders", "Provider") });
}
I had written the following Test case for the above method,which was working
[TestMethod()]
public void CreateProviderTest()
{
mockProviderRepository.Setup(provider => provider.CreateProvider(_provider)).Returns(new int());
var providerCreationResult = _providerController.CreateProvider(_provider) as ActionResult;
Assert.IsNotNull(providerCreationResult);
}
As can be seen from my code in the action method,I am redirecting using AJAX,hence returning JSON of the url to be redirected to.
Now,the test is obviously failing.I am new to unit tests and was wondering,what updates I needed to make to the Testmethod for it to pass.Please guide me.Thanks.
If you want test the Json Result contains the expected URL, you can write a test like below.
[TestMethod]
public void CreateProvider_Execute_EnsureJsonContainsExpectedUrl()
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(x => x);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
RouteConfig.RegisterRoutes(new RouteCollection());
var repoStub = new Mock<IRepository>();
repoStub.Setup(x => x.CreateProvider(new Provider())).Returns(1);
var sut = new HomeController(repoStub.Object, new Mock<ILogger>().Object);
sut.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);
var result = sut.CreateProvider(new Provider()) as JsonResult;
var actualUrl = GetValueFromJsonResult<string>(result, "url");
Assert.AreEqual<string>("/Provider/ShowTheListOfProviders", actualUrl);
}
private T GetValueFromJsonResult<T>(JsonResult jsonResult, string propertyName)
{
var property =
jsonResult.Data.GetType().GetProperties()
.Where(p => string.Compare(p.Name, propertyName) == 0)
.FirstOrDefault();
if (null == property)
throw new ArgumentException("propertyName not found", "propertyName");
return (T)property.GetValue(jsonResult.Data, null);
}
Related
I am writing unit tests for DocumentDBRepository but I got a null reference exception. I use Moq framework and XUnit.
Here's my methods in DocumentDBRepository class.
public class DocumentDBRepository<T> : IRepository<T> where T: class
{
private static string DatabaseId;
private static string CollectionId;
private static IDocumentClient client;
public DocumentDBRepository(IDocumentClient documentClient, string databaseId, string collectionId)
{
DatabaseId = databaseId;
CollectionId = collectionId;
client = documentClient;
CreateDatabaseIfNotExistsAsync().Wait();
CreateCollectionIfNotExistsAsync().Wait();
}
public async Task<IDocumentQuery<T>> GetQuery(Expression<Func<T, bool>> predicate)
{
try
{
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true })
.Where(predicate)
.AsDocumentQuery();
return query;
}
catch (Exception e) {
throw;
}
}
public async Task<IEnumerable<T>> GetEntities(IDocumentQuery<T> query)
{
try
{
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
}
catch (Exception e)
{
throw;
}
}
}
Here's my test code:
public interface IFakeDocumentQuery<T> : IDocumentQuery<T>, IOrderedQueryable<T>
{
}
[Fact]
public async virtual Task Test_GetBooksById()
{
var expected = new List<Book> {
new Book { ID = "123", Description = "HarryPotter"},
new Book { ID = "124", Description = "HarryPotter2"} };
var response = new FeedResponse<Book>(expected);
var mockDocumentQuery = new Mock<IFakeDocumentQuery<Book>>();
mockDocumentQuery.SetupSequence(_ => _.HasMoreResults)
.Returns(true)
.Returns(false);
mockDocumentQuery.Setup(_ => _.ExecuteNextAsync<Book>(It.IsAny<CancellationToken>()))
.ReturnsAsync(response);
var client = new Mock<IDocumentClient>();
client.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);
var documentsRepository = new DocumentDBRepository<Book>(client.Object, "123", "123");
//Act
var query = await documentsRepository.GetQuery(t => t != null);
var entities = await documentsRepository.GetEntities(query);
//Assert
if (entities != null)
{
entities.Should().BeEquivalentTo(expected);
}
}
Here's the error message after running the test method:
Message: System.NullReferenceException : Object reference not set to
an instance of an object.
When I stepped through the code, the error happens right after the the test code called GetQuery() method:
IDocumentQuery<T> query = client.CreateDocumentQuery<T>(
UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true })
.Where(predicate)
.AsDocumentQuery();
Here's my thought process: when I stepped through the entire code, I do not see any null variables. But in the 'response' variable from the second line of the test method, it does show a lot of the properties are null exception but result view shows the 'expected' variable.
My question is, is it because of the response variable that caused the null reference exception? Or somewhere else?
PS: Test code reference from here
I also tried turning on the Mock behavior to strict and saw this error message.
Message: System.AggregateException : One or more errors occurred.
(IDocumentClient.ReadDatabaseAsync(dbs/123, null) invocation failed
with mock behavior Strict. All invocations on the mock must have a
corresponding setup.)
---- Moq.MockException : IDocumentClient.ReadDatabaseAsync(dbs/123, null) invocation failed with mock behavior Strict. All invocations on
the mock must have a corresponding setup.
As suspected the problem is .Where(predicate). I ran a test with the provided example and removed the .Where clause and it executed to completion.
The fake interface inherits from both IOrderedQueryable and IDocumentQuery. The issue is that the Where is converting it back to a plain IEnumerable because of the List data source and the AsDocumentQuery is crapping out as it is expecting an IDocumentQuery
I am not a fan of tightly coupling to APIs I can't control. I would abstract my way around such implementation details for that very reason.
The work around involved having to provide a fake Linq IQueryProvider to bypass any queries and return a type that derives from IDocumentQuery so as to allow AsDocumentQuery to behave as intended.
But first I refactored GetEntities and made GetQuery private to stop the repository from being a leaky abstraction.
private IDocumentQuery<T> getQuery(Expression<Func<T, bool>> predicate) {
var uri = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);
var feedOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = true };
var queryable = client.CreateDocumentQuery<T>(uri, feedOptions);
IQueryable<T> filter = queryable.Where(predicate);
IDocumentQuery<T> query = filter.AsDocumentQuery();
return query;
}
public async Task<IEnumerable<T>> GetEntities(Expression<Func<T, bool>> predicate) {
try {
IDocumentQuery<T> query = getQuery(predicate);
var results = new List<T>();
while (query.HasMoreResults) {
results.AddRange(await query.ExecuteNextAsync<T>());
}
return results;
} catch (Exception e) {
throw;
}
}
Note that getQuery is not doing anything async so it should not be returning a Task<> anyway.
Next in the test the mocked IDocumentQuery was set up to allow the test to flow to completion. This was done by providing a mocked IQueryProvider the would return the mocked IDocumentQuery when Linq queries are invoked against it. (which was the cause of the problem to begin with)
public async virtual Task Test_GetBooksById() {
//Arrange
var id = "123";
Expression<Func<Book, bool>> predicate = t => t.ID == id;
var dataSource = new List<Book> {
new Book { ID = id, Description = "HarryPotter"},
new Book { ID = "124", Description = "HarryPotter2"}
}.AsQueryable();
var expected = dataSource.Where(predicate);
var response = new FeedResponse<Book>(expected);
var mockDocumentQuery = new Mock<IFakeDocumentQuery<Book>>();
mockDocumentQuery
.SetupSequence(_ => _.HasMoreResults)
.Returns(true)
.Returns(false);
mockDocumentQuery
.Setup(_ => _.ExecuteNextAsync<Book>(It.IsAny<CancellationToken>()))
.ReturnsAsync(response);
var provider = new Mock<IQueryProvider>();
provider
.Setup(_ => _.CreateQuery<Book>(It.IsAny<System.Linq.Expressions.Expression>()))
.Returns((Expression expression) => {
if (expression != null) {
dataSource = dataSource.Provider.CreateQuery<Book>(expression);
}
mockDocumentQuery.Object;
});
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.Provider).Returns(provider.Object);
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.Expression).Returns(() => dataSource.Expression);
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.ElementType).Returns(() => dataSource.ElementType);
mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.GetEnumerator()).Returns(() => dataSource.GetEnumerator());
var client = new Mock<IDocumentClient>();
client.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
.Returns(mockDocumentQuery.Object);
var documentsRepository = new DocumentDBRepository<Book>(client.Object, "123", "123");
//Act
var entities = await documentsRepository.GetEntities(predicate);
//Assert
entities.Should()
.NotBeNullOrEmpty()
.And.BeEquivalentTo(expected);
}
This allowed the test to be exercised to completion, behave as expected, and pass the test.
I try to create unit testing my authorization logic, but have problem for testing
await this.HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme)));
I have error
No authentication handler is configured to handle the scheme: Cookies
Because he need CookieAuthenticationOptions
But how configuration for unit test I don't know
private static Mock<SignInManager<User>> GetSignInManagerMock(Mock<UserManager<User>> userManagerMock)
{
var context = new Mock<HttpContext>();
var contextAccessor = new Mock<IHttpContextAccessor>();
contextAccessor.Setup(x => x.HttpContext).Returns(context.Object);
return new Mock<SignInManager<User>>(userManagerMock.Object,
contextAccessor.Object,
new Mock<IUserClaimsPrincipalFactory<User>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<ILogger<SignInManager<User>>>().Object);
}
private static Mock<UserManager<User>> GetUserManagerMock()
{
return new Mock<UserManager<User>>(new Mock<IUserStore<User>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<User>>().Object,
new IUserValidator<User>[0],
new IPasswordValidator<User>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<User>>>().Object);
}
[Fact]
public async void Login_Corect_input_login_password_should_return_ok()
{
var stamp = Guid.NewGuid().ToString();
var user = new User
{
UserName = _fakeUserModel.UserName,
Email = _fakeUserModel.Email,
FirtName = _fakeUserModel.FirstName,
LastName = _fakeUserModel.LastName,
UserPicture = _fakeUserModel.UserPicture,
ConcurrencyStamp = stamp
};
var userManagerMock = GetUserManagerMock();
userManagerMock.Setup(s => s.FindByNameAsync(FakeData.UserName)).ReturnsAsync(user);
userManagerMock.Setup(s => s.GetRolesAsync(user)).ReturnsAsync(FakeData.Roles);
var signInManagerMock = GetSignInManagerMock(userManagerMock);
signInManagerMock.Setup(
s =>
s.PasswordSignInAsync(_fakeCorrectloginModel.UserName, _fakeCorrectloginModel.Password, false,
false))
.ReturnsAsync(Microsoft.AspNetCore.Identity.SignInResult.Success);
var controller = ControllerFactory.CreateFakeController<UserController>(false, userManagerMock.Object,
signInManagerMock.Object);
var response = await controller.Login(_fakeCorrectloginModel);
var result = Assert.IsType<JsonResult>(response);
var getModel = Assert.IsType<UserViewModel>(result.Value);
Assert.Equal(_fakeUserModel, getModel);
}
public static class ControllerFactory
{
public static T CreateFakeController<T>(bool isLoggedIn, params object[] arg) where T : Controller
{
var fakePrincipal = GetPrincipalMock(isLoggedIn).Object;
var fakeActionContext = new ActionContext
{
HttpContext = new DefaultHttpContext
{
User = fakePrincipal
},
ActionDescriptor = new ControllerActionDescriptor(),
RouteData = new RouteData()
};
var controller = (T)Activator.CreateInstance(typeof(T), arg);
controller.ControllerContext = new ControllerContext(fakeActionContext);
return controller;
}
public static Mock<ClaimsPrincipal> GetPrincipalMock(bool isLoggedIn)
{
var principalMock = new Mock<ClaimsPrincipal>();
principalMock.Setup(sg => sg.Identity).Returns(GetIdentityMock(isLoggedIn).Object);
principalMock.Setup(s => s.IsInRole(It.IsAny<string>())).Returns(false);
principalMock.Setup(s => s.Claims).Returns(new List<Claim>
{
GetClaim(HelpClaimTypes.Language, "ua")
});
return principalMock;
}
public static Mock<ClaimsIdentity> GetIdentityMock(bool isLoggedIn)
{
var identityMock = new Mock<ClaimsIdentity>();
identityMock.Setup(sg => sg.AuthenticationType).Returns(isLoggedIn ? FakeData.AuthenticationType : null);
identityMock.Setup(sg => sg.IsAuthenticated).Returns(isLoggedIn);
identityMock.Setup(sg => sg.Name).Returns(isLoggedIn ? FakeData.UserName : null);
return identityMock;
}
public static ClaimsIdentity GetClaimsIdentity(params Claim[] claims)
{
var identityMock = new ClaimsIdentity(claims);
return identityMock;
}
public static Claim GetClaim(string type, string value)
{
return new Claim(type, value);
}
}
I am trying to build a unit test to make sure an unauthenticated user is unable to reach a controller. when i run the test, the users is being found as authenticated. how do i mock things up so that the test finds the mocked user as unauthenticated.
i am using mvc5 with indentity 2.0
controller
[Authorize]
public class ProfileController : Controller
{
private ICompanyServiceLayer _service;
public ProfileController(ICompanyServiceLayer service)
{
_service = service;
}
public ActionResult Index(int id)
{
/* cool stuff happens here */
return View();
}
}
test
[Test]
public void Index_As_Annonymous_User()
{
// arrange
Mock<ICompanyServiceLayer> service = new Mock<ICompanyServiceLayer>();
GenericIdentity id = new GenericIdentity("");
Mock<IPrincipal> princ = new Mock<IPrincipal>();
princ.Setup(x => x.Identity).Returns(id);
Mock<HttpContextBase> contextBase = new Mock<HttpContextBase>();
contextBase.Setup(x => x.User).Returns(princ.Object);
Mock<ControllerContext> controllerContext = new Mock<ControllerContext>();
controllerContext.Setup(x => x.HttpContext).Returns(contextBase.Object);
// controller
ProfileController controller = new ProfileController(service.Object);
controller.ControllerContext = controllerContext.Object;
// act
var result = controller.Index(1);
// assert
Assert.IsInstanceOf(typeof(HttpStatusCodeResult), result);
}
update based on blorkfish suggestion
[Test]
public void Index_As_Annonymous_User()
{
// arrange
Mock<ICompanyServiceLayer> service = new Mock<ICompanyServiceLayer>();
Mock<HttpRequestBase> request = new Mock<HttpRequestBase>();
request.Setup(x => x.IsAuthenticated).Returns(false);
Mock<HttpContextBase> contextBase = new Mock<HttpContextBase>();
contextBase.Setup(x => x.Request).Returns(request.Object);
// controller
ProfileController controller = new ProfileController(service.Object);
controller.ControllerContext = new ControllerContext(contextBase.Object, new RouteData(), controller);
// act
var result = controller.Index(1);
// assert
Assert.IsInstanceOf(typeof(HttpStatusCodeResult), result);
}
Using Moq, you need to mock the HttpContextBase and ensure its IsAuthenticated property returns false.
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.SetupGet(c => c.User.Identity.IsAuthenticated).Returns(false);
var mockControllerContext = new Mock<ControllerContext>();
mockControllerContext.Setup(c => c.HttpContext).Returns(mockHttpContext.Object);
controller.ControllerContext = mockControllerContext.Object;
Then, running the following in your controller action should return false:
User.Identity.IsAuthenticated
The mvc framework checks the HttpRequest.IsAuthenticated flag. To mock this, you will need to mock the httpContext and the httpRequest:
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
httpContext.Stub(x => x.Request).Return(httpRequest);
httpRequest.Stub(x => x.IsAuthenticated).Return(false);
UserController controller = new UserController();
controller.ControllerContext
= new ControllerContext(httpContext, new RouteData(), controller);
I would like to mock a WebViewPage and compare the output with an expected result.
here are my mockhelpers I'm using
public static class MockHelpers
{
public static HttpContextBase MockHttpContext(NameValueCollection queryStringCollection = null)
{
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
if(queryStringCollection != null)
SetupMockRequestQuerystringValues(request, queryStringCollection);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url);
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method
context.SetupGet(p => p.User.Identity.Name).Returns("blah");
context.SetupGet(p => p.User.Identity.IsAuthenticated).Returns(true);
return context.Object;
}
private static void SetupMockRequestQuerystringValues( Mock<HttpRequestBase> request, NameValueCollection queryStringCollection)
{
request.SetupGet(x => x.QueryString).Returns(queryStringCollection);
}
public static ViewContext MockViewContext()
{
return CreateSimpleGenericMock<ViewContext>();
}
public static T MockWebViewPage<T>() where T : WebViewPage
{
var mock = new Mock<T>(MockBehavior.Loose) { CallBase = true };
mock.SetupGet(x => x.Context).Returns(MockHttpContext());
mock.SetupGet(x => x.Layout).Returns("layoutName");
mock.SetupGet(x => x.VirtualPath).Returns("virtualPathName");
mock.SetupGet(x => x.Page).Returns(new object{});
mock.SetupGet(x => x.PageData).Returns(new Dictionary<object, dynamic>()
{
{new object(), new object()}
});
var page = mock.Object;
//var helper = new HtmlHelper<object>(new ViewContext { ViewData = CreateSimpleGenericMock<ViewDataDictionary>() }, page, CreateSimpleGenericMock<RouteCollection>());
var helper = new HtmlHelper<object>(new ViewContext { ViewData = new ViewDataDictionary() }, page, new RouteCollection());
page.ViewContext = MockViewContext();
page.Html = helper;
return page;
}
public static T CreateSimpleGenericMock<T>() where T : class
{
var mock = new Mock<T>();
return mock.Object;
}
}
In the MockWebViewPage method you can see all that I have faked. My test method looks like so
[TestMethod]
public void TestMethod1()
{
var coreMasterTestClass = MockHelpers.MockWebViewPage<CoreMaster<object>>();
coreMasterTestClass.ExecutePageHierarchy();
var output = coreMasterTestClass.Html;
}
Is it possible to test the output that will be generated with mocking, and if not does anyone have any possible clues how I could test this. Please note that I'm not testing actual chstml pages but core pages within our own framework.
I am running unit tests on code which uses VirtualParthUtility.GetAbsolute, but am having problems mocking the context for this to work.
I've set up a mock context with Moq as follows
private Mock<HttpContextBase> MakeMockHttpContext(string url) // url = "~/"
{
var mockHttpContext = new Mock<HttpContextBase>();
// Mock the request
var mockRequest = new Mock<HttpRequestBase>();
mockRequest.Setup(x => x.ApplicationPath).Returns("/");
mockRequest.Setup(x => x.Path).Returns("/");
mockRequest.Setup(x => x.PathInfo).Returns(string.Empty);
mockRequest.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url);
mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object);
// Mock the response
var mockResponse = new Mock<HttpResponseBase>();
mockResponse.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns((string s) => s);
mockHttpContext.Setup(x => x.Response).Returns(mockResponse.Object);
return mockHttpContext;
}
And attached this to an MVC Controller
_myController.ControllerContext = new ControllerContext(MakeMockHttpContext("~/").Object, new RouteData(), _slideSelectorController);
The code that runs during the test hits the line:
venue.StyleSheetUrl = VirtualPathUtility.ToAbsolute(venue.StyleSheetUrl); // input like "~/styles/screen.css"
Every time this runs, it steps into System.Web.VirtualPathUtility, with the problem that the "VirtualParthString" to be returned always throws an exception:
public static string ToAbsolute(string virtualPath)
{
return VirtualPath.CreateNonRelative(virtualPath).VirtualPathString;
}
The reason for the exception is easy to see in System.Web.VirtualPathString:
public string VirtualPathString
{
get
{
if (this._virtualPath == null)
{
if (HttpRuntime.AppDomainAppVirtualPathObject == null)
{
throw new HttpException(System.Web.SR.GetString("VirtualPath_CantMakeAppAbsolute", new object[] { this._appRelativeVirtualPath }));
}
if (this._appRelativeVirtualPath.Length == 1)
{
this._virtualPath = HttpRuntime.AppDomainAppVirtualPath;
}
else
{
this._virtualPath = HttpRuntime.AppDomainAppVirtualPathString + this._appRelativeVirtualPath.Substring(2);
}
}
return this._virtualPath;
}
}
Through the Watch Window I can see that _virtualPath and HttpRuntime.AppDomainAppVirtualPathString are both null, hence it throws an exception.
If _virtualPath were set, the exception wouldn't happen. But after the VirtualPath.Create method has created a new VirtualPath object, it doesn't set the _virtualPath property before it is returned. An extract from the Create method up to this point is:
VirtualPath path = new VirtualPath();
if (UrlPath.IsAppRelativePath(virtualPath))
{
virtualPath = UrlPath.ReduceVirtualPath(virtualPath);
if (virtualPath[0] == '~')
{
if ((options & VirtualPathOptions.AllowAppRelativePath) == 0)
{
throw new ArgumentException(System.Web.SR.GetString("VirtualPath_AllowAppRelativePath", new object[] { virtualPath }));
}
path._appRelativeVirtualPath = virtualPath;
return path;
So if anyone can suggest how to get this unit test working, that will be very helpful!
Thanks,
Steve
I would just create a wrapper interface. Something like:
public interface IPathUtilities
{
string ToAbsolute(string virtualPath);
}
You can inject that into your controller. At test time, use a stub. At runtime, you'll have a class that implements IPathUtilities and calls VirtualPathUtility.ToAbsolute().