Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

inject localization in tests without AbpIntegratedTestBase #1836


User avatar
0
carelearning created

When we try to resolve ILocalizationManager in a test it fails. If we change our test class to inherit from AbpIntegratedTestBase then it runs, but the tests take many, many times longer to run. What is the best way to resolve ILocalizationManager in the test project without incurring the time penalty of the AppTestBase class?

We are using moq to work around the issue we had here 8888. The code we are trying to write looks like:

public class MigrationAppService_Tests
{
    private readonly ILocalizationManager _localizationManager;
    private readonly Mock<IRepository<Tenant>> _mockReposistory;        
    
    public MigrationAppService_Tests()
    {
        _mockReposistory = new Mock<IRepository<Tenant>>();
        _mockReposistory.Setup(x => x.GetAsync(1))
                        .Returns(Task.FromResult((Tenant)new TenantBuilder()));

        _localizationManager = IocManager.Instance.Resolve<ILocalizationManager>();
    }

    [Fact]
    public async Task IfTenantIdParameterIsMissingSaveZipAsyncReturnsExpectedErrorMessage()
    {
        var expected = "Tenant id was not found.";

        MigrationAppService sut = new MigrationAppServiceBuilder()
                                        .WithLocalizationManager(_localizationManager)
                                        .WithTenantRepository(_mockReposistory.Object);

        var result = await sut.SaveZipAsync(-1, null);
        result.ErrorMessage.ShouldBe(expected);
    }
}

When run, we get this error:

Castle.MicroKernel.ComponentNotFoundException
No component for supporting the service Abp.Localization.ILocalizationManager was found
   at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)
   at Castle.Windsor.WindsorContainer.Resolve[T]()
   at MyCompanyName.AbpZeroTemplate.Tests.Migration.MigrationAppService_Tests..ctor() in C:\projects\port\src\Tests\MyCompanyName.AbpZeroTemplate.Tests\Migration\MigrationAppService_Tests.cs:line 36

When we try to mock around this issue with something like this:

[Fact]
       public async Task IfTenantIdParameterIsMissingSaveZipAsyncReturnsExpectedErrorMessage()
       {
           const string Expected = "Tenant id was not found.";

           var mockLocalizationSource = new Mock<ILocalizationSource>();
           mockLocalizationSource.Setup(x => x.GetString(It.IsAny<string>()))
                                  .Returns(Expected);

           _mockLocalizationManager.Setup(x => x.GetSource(It.IsAny<string>()))
                       .Returns(mockLocalizationSource.Object);

           MigrationAppService sut = new MigrationAppServiceBuilder()
                                           .WithLocalizationManager(_mockLocalizationManager.Object)
                                           .WithTenantRepository(_mockReposistory.Object);

           var result = await sut.SaveZipAsync(-1, null);
           _mockLocalizationManager.Verify(x => x.GetSource("Custom"), Times.Once);
           mockLocalizationSource.Verify(x => x.GetString(MigrationError.TenantIdMissing.ToString()), Times.Once());

           result.ErrorMessage.ShouldBe(Expected);
       }

Then it seems like we are not writing good tests--we are just testing the mocks.

Thank you.


1 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    You can use NullLocalizationManager instead of ILocalizationManager, which returns given text for localization. You probably don't need to actually localize tests in tests. to do that:

    LocalIocManager.IocContaier.Register(Component.For<ILocalizationManager>().Instance(NullLocalizationManager.Instance));
    

    Have a nice day.