Home > Software engineering >  Mock the Request when testing a Razor Page
Mock the Request when testing a Razor Page

Time:11-30

I need to create a unit test for this function that resides inside the HomeModel razor page

public async Task<IActionResult> OnGetCurrencyAsync(string currency, CancellationToken ct = default)
{
    var returnUrl = Request.Headers["Referer"].ToString();
    var path = new System.Uri(returnUrl).LocalPath;

    if (string.IsNullOrWhiteSpace(path) || !Url.IsLocalUrl(path))
        returnUrl = Url.Content("~/");

    var session = await _currentUserService.GetOrInitializeSessionAsync(ct);
    if (!currency.IsNullOrEmpty())
    {
        session.Currency = currency;
        await _currentUserService.SetSession(session, ct);
    }

    return Redirect(returnUrl);
}

Till now I've created the following test

[Fact]
public async Task Test1()
{
    var returnUrl = "https://localhost:44317/paris";

    var currentuserService = new Mock<ICurrentUserService>();
    var options = new Mock<IOptions<Core.Configuration.AppSettings>>();
    var navigationMenu = new Mock<INavigationMenu>();
    var productModelService = new Mock<IProductModelService>();
    var userSavedProductRepository = new Mock<IUserSavedProductRepository>();
    var userSavedProductService = new Mock<IUserSavedProductService>();

    var homePage = new HomeModel(currentuserService.Object, options.Object, navigationMenu.Object, productModelService.Object, userSavedProductService.Object, userSavedProductRepository.Object);

    
    var res = await homePage.OnGetCurrencyAsync("EUR", CancellationToken.None);

    Assert.IsType<RedirectResult>(res);

    var redirectResult = (RedirectResult)res;

    Assert.True(returnUrl == redirectResult.Url);
}

But when I execute it, I got that .Request is null..

How can I correctly set it up?

CodePudding user response:

The PageContext of the subject PageModel needs a HttpContext that contains the desired Request setup to satisfy the subject under test.

Reference: Razor Pages unit tests in ASP.NET Core: Unit tests of the page model methods

//Arrange
var returnUrl = "https://localhost:44317/paris";


//...code omitted for brevity


// use a default context to have access to a request
var httpContext = new DefaultHttpContext();
httpContext.Request.Headers["Referer"] = returnUrl; //<--

//these are needed as well for the page context
var modelState = new ModelStateDictionary();
var actionContext = new ActionContext(httpContext, new RouteData(), new PageActionDescriptor(), modelState);
var modelMetadataProvider = new EmptyModelMetadataProvider();
var viewData = new ViewDataDictionary(modelMetadataProvider, modelState);
// need page context for the page model
var pageContext = new PageContext(actionContext) {
    ViewData = viewData
};

//create model with necessary dependencies applied
var homePage = new HomeModel(currentuserService.Object, options.Object, navigationMenu.Object, productModelService.Object, userSavedProductService.Object, userSavedProductRepository.Object) {
    PageContext = pageContext, //<--
    Url = new UrlHelper(actionContext)
};

//Act

//...omitted for brevity
  • Related