Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net core testing controller with IStringLocalizer

I have controller with localization

public class HomeController : Controller
{
    private readonly IStringLocalizer<HomeController> _localizer;

    public HomeController(IStringLocalizer<HomeController> localizer)
    {
        _localizer = localizer;
    }

    [HttpPost]
    public IActionResult SetLanguage(string culture, string returnUrl)
    {
        Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
            new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
        );

        return LocalRedirect(returnUrl);
    }

    public IActionResult Index()
    {
        ViewData["MyTitle"] = _localizer["Hello my dear friend!"];

        return View("Index");
    }
}

and I added xUnit project for testing and wrote next code

public class HomeControllerTest
{
    private readonly IStringLocalizer<HomeController> _localizer;
    private HomeController _controller;
    private ViewResult _result;

    public HomeControllerTest()
    {
        _controller = new HomeController(_localizer);
        _result = _controller.Index() as ViewResult;
    }

    [Fact]
    public void IndexViewDataMessage()
    {
        // Assert
        Assert.Equal("Hello my dear friend!", _result?.ViewData["MyTitle"]);
    }

    [Fact]
    public void IndexViewResultNotNull()
    {
        // Assert
        Assert.NotNull(_result);
    }

    [Fact]
    public void IndexViewNameEqualIndex()
    {
        // Assert
        Assert.Equal("Index", _result?.ViewName);
    }
}

When I running all tests, they returns false with exception:

Message: System.NullReferenceException : Object reference not set to an instance of an object.

When you double-click on a method in the StackTrace cursor appears on the line

ViewData["MyTitle"] = _localizer["Hello my dear friend!"];

I think this is due to IStringLocalizer. How to fix it? May be somebody knows what is the reason?

like image 713
Артём Игнатьев Avatar asked Apr 17 '17 22:04

Артём Игнатьев


People also ask

What is istringlocalizer in ASP NET Core?

Introduced in ASP.NET Core, IStringLocalizer and IStringLocalizer<T> were architected to improve productivity when developing localized apps. IStringLocalizer uses the ResourceManager and ResourceReader to provide culture-specific resources at run time.

Do you test controllers in ASP NET Core Applications?

Sure we do. In this article, we are going to talk more about testing controllers in ASP.NET Core applications by using Moq and unit tests. To download the source code for this article, you can visit our GitHub repository. For the complete navigation of this series, you can visit ASP.NET Core Testing. So, let’s get going.

What is integration test in ASP NET Core?

Thank you. Integration tests ensure that an app's components function correctly at a level that includes the app's supporting infrastructure, such as the database, file system, and network. ASP.NET Core supports integration tests using a unit test framework with a test web host and an in-memory test server.

What is a unit test in ASP NET controller?

A controller unit test avoids scenarios such as filters, routing, and model binding. Tests that cover the interactions among components that collectively respond to a request are handled by integration tests. For more information on integration tests, see Integration tests in ASP.NET Core.


2 Answers

Setup the mock to return your expected result.

var mock = new Mock<IStringLocalizer<HomeController>>();
string key = "Hello my dear friend!";
var localizedString = new LocalizedString(key, key);
mock.Setup(_ => _[key]).Returns(localizedString);

_localizer = mock.Object;
_controller = new HomeController(_localizer);
like image 108
Nkosi Avatar answered Oct 08 '22 08:10

Nkosi


If you need strings from the actual localized resources in your tests you can add the Microsoft.AspNetCore.All Nuget package to your test project and then use the following code:

var options = Options.Create(new LocalizationOptions {ResourcesPath = "Resources"});
var factory = new ResourceManagerStringLocalizerFactory(options, NullLoggerFactory.Instance);
var localizer = new StringLocalizer<HomeController>(factory);

The ResourcesPath should be the relative path of where HomeController.en.resx is found from the project root.

like image 34
Naylor Avatar answered Oct 08 '22 09:10

Naylor