带有IStringLocalizer的asp.net核心测试控制器

Арт*_*ьев 7 unit-testing localization xunit .net-core asp.net-core

我有本地化的控制器

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我添加了xUnit项目进行测试并编写了下一个代码

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行所有测试时,它们返回false,但异常:

消息:System.NullReferenceException:未将对象引用设置为对象的实例.

双击StackTrace游标中的方法时出现在该行上

ViewData["MyTitle"] = _localizer["Hello my dear friend!"];
Run Code Online (Sandbox Code Playgroud)

我认为这是由于IStringLocalizer.怎么解决?可能有人知道是什么原因?

Nay*_*lor 15

如果您在测试中需要来自实际本地化资源的字符串,您可以将Microsoft.AspNetCore.All Nuget 包添加到您的测试项目,然后使用以下代码:

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

ResourcesPath应该在哪里HomeController.en.resx从项目根目录的相对路径。


Nko*_*osi 12

设置模拟以返回预期结果.

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);
Run Code Online (Sandbox Code Playgroud)

  • 是否有机会为 IStringLocalizer 设置手动区域设置?我正在尝试测试一个调用 IStringLocalizer&lt;MyClass&gt; 的方法,我正在传递它的一个实例,但无法弄清楚如何设置区域设置。我尝试了 `_myLocalizerVar.WithCulture(new CultureInfo("fr-FR"))`,但它创建了 StringLocalizer 的新实例,这不是我想要的。 (2认同)