0

I have a test Class that at some point Localizes a String with using the GetString(IStringLocalizer, String, Object[]) Extension-Method

The follwing will work except for testing

public class ClassToTest
{
    private readonly IStringLocalizer<SharedResource> _localizer;
    
    public AnalyticsLogic(IStringLocalizer<SharedResource> localizer)
    {
        _localizer = localizer;
    }
    
    public async Task<string> SomeMethod()
    {
        return _localizer.GetString("key", DateTime.Today));  // "My Date: 31.10.2018" - will return null when testing
    }       

    public async Task<string> SomeMethod2()
    {
        return _localizer.GetString("key");  // "My Date: {0:d}"
    }
}

This is how i built up my test:

public class ClassToTestTest
{
    private readonly ClassToTest _testee;
    private readonly Mock<IStringLocalizer<SharedResource>> _localizerMock = new Mock<IStringLocalizer<SharedResource>>();

    public ClassToTestTest()
    {
        _testee = new ClassToTest(_localizerMock.Object);

        _localizerMock.Setup(lm => lm["key"]).Returns(new LocalizedString("key", "My Date: {0:d}"));
    }



    [Fact]
    public async Task SomeMethod()
    {
        var result = await _testee.SomeMethod();

        Assert.Equal($"My Date: {new DateTime(2018, 10, 31):d}", result);
    }

    [Fact]
    public async Task SomeMethod2()
    {
        var result = await _testee.SomeMethod2();

        Assert.Equal("My Date: {0:d}", result);
    }
}

Running the Test will fail with the following error:

SomeMethod() failed

  • Assert.Equal() Failure
  • Expected: My Date: 31.10.2018
  • Actual: (null)

Usually I would simply assume the Method GetString(IStringLocalizer, String, Object[]) not to be able to handle format strings, but since im using this in a productive environment and it works, I have no clue how this may be fixed. To me it seems like I have properly mocked the _localizer dependency. Otherwise the GetString(IStringLocalizer, String) would not return the format-string.

Edit:

For clarification:

  • Test SomeMethod() will fail
  • Test SomeMethod2() will succeed
Community
  • 1
  • 1
LuckyLikey
  • 3,504
  • 1
  • 31
  • 54
  • if the mock returns null it usually means that the mock did not get what was expected when invoked. – Nkosi Oct 31 '18 at 11:39
  • @Nkosi its not the mock that returns null, its the extension-Method `GetString(IStringLocalizer, String, Object[])` used in `SomeMethod()` that will not work. The extension-Method `GetString(IStringLocalizer, String)` as used in `SomeMethod2()` works just fine. – LuckyLikey Oct 31 '18 at 11:47

1 Answers1

5

If you look at the code for the GetString extension methods, the version that takes just a string does use the method you have mocked but the version that takes extra parameters doesn't:

return stringLocalizer[name, arguments];

So you need to be mocking this additional method of IStringLocalizer:

LocalizedString this[string name, params object[] arguments] { get; }

Which I am guessing is something like this:

_localizerMock.Setup(lm => lm["key", It.IsAny<object[]>()])
    .Returns(new LocalizedString("key", "My Date: {0:d}"));
DavidG
  • 113,891
  • 12
  • 217
  • 223