I am using abp 4.4.2 and want to implement some test for one simple crud application service which has no custom code and only inherits from CrudAppService. The entity in this service is an IMultiTenant and I want to check the GetListAsync method with different tenant Ids. I have mocked the ICurrentTenant in the application test base to mock the tenant login like below, however when I use my LoginAsDefaultTenant method, I get a stack overflow error in AutoFac module.
public abstract class OrderManagementApplicationTestBase : OrderManagementTestBase<OrderManagementApplicationTestModule>
{
private ICurrentTenant _fakeCurrentTenant;
private ICurrentUser _fakeCurrentUser;
protected override void AfterAddApplication(IServiceCollection services)
{
_fakeCurrentTenant = Substitute.For<ICurrentTenant>();
_fakeCurrentUser = Substitute.For<ICurrentUser>();
services.AddSingleton(_fakeCurrentTenant);
services.AddSingleton(_fakeCurrentUser);
}
protected void LoginAsHostAdmin()
{
_fakeCurrentTenant.Id.Returns(ci => null);
_fakeCurrentTenant.Name.Returns(ci => null);
}
protected void LoginAsDefaultTenant()
{
_fakeCurrentTenant.Id.Returns(ci => Guid.Parse(OrderManagementTestData.DefaultTenantId));
_fakeCurrentTenant.Name.Returns(ci => TestData.DefaultTenantName);
_fakeCurrentUser.Id.Returns(ci => TestData.DefaultTenantAdminUserId);
_fakeCurrentUser.TenantId.Returns(ci => Guid.Parse(OrderManagementTestData.DefaultTenantId));
}
These unit tests are passing ok:
[Fact]
public void LoginAsHostAdmin_Should_Return_CorrectTenantIdAndUserId()
{
// Arrange, Act
LoginAsHostAdmin();
var currentTenant = GetRequiredService<ICurrentTenant>();
var currentUser = GetRequiredService<ICurrentUser>();
// Assert
currentTenant.Id.ShouldBeNull();
currentTenant.Name.ShouldBeNull();
}
[Fact]
public void LoginAsDefaultTenant_Should_Return_CorrectTenantIdAndUserId()
{
// Arrange, Act
LoginAsDefaultTenant();
var currentTenant = GetRequiredService<ICurrentTenant>();
var currentUser = GetRequiredService<ICurrentUser>();
// Assert
currentTenant.Id.ShouldBe(Guid.Parse(OrderManagementTestData.DefaultTenantId));
currentTenant.Name.ShouldBe(TestData.DefaultTenantName);
currentUser.Id.ShouldBe(TestData.DefaultTenantAdminUserId);
currentUser.TenantId.ShouldBe(Guid.Parse(OrderManagementTestData.DefaultTenantId));
}
Here is my service code and it's unit test which is failing.
[Authorize(OrderManagementPermissions.MENUS_MANAGEMENT)]
public class MenuAppService
: CrudAppService<
Menu,
MenuDto,
Guid,
ListMenuRequestDto,
CreateUpdateMenuDto>,
IMenuAppService
{
private readonly IRepository<Menu, Guid> _menuRepository;
public MenuAppService(IRepository<Menu, Guid> menuRepository) : base(menuRepository)
{
_menuRepository = menuRepository;
GetListPolicyName = OrderManagementPermissions.MENUS_MANAGEMENT_LIST;
GetPolicyName = OrderManagementPermissions.MENUS_MANAGEMENT_GET;
CreatePolicyName = OrderManagementPermissions.MENUS_MANAGEMENT_CREATE;
UpdatePolicyName = OrderManagementPermissions.MENUS_MANAGEMENT_UPDATE;
DeletePolicyName = OrderManagementPermissions.MENUS_MANAGEMENT_DELETE;
}
}
public class MenusAppService_Tests : OrderManagementApplicationTestBase
{
private IMenuAppService _menuAppService;
public MenusAppService_Tests()
{
_menuAppService = GetRequiredService<IMenuAppService>();
}
[Fact]
public async Task GetListAsync_Filter_Tests()
{
// Arrange
LoginAsDefaultTenant();
var listRequestDto = new ListMenuRequestDto();
listRequestDto.RestaurantId = Guid.Parse(OrderManagementTestData.DefaultRestaurantId);
// Act
var list = await _menuAppService.GetListAsync(listRequestDto);
// Assert
list.ShouldNotBeNull();
list.Items.Count.ShouldBe(2);
list.Items.ShouldContain(m => m.Title == TestData.MenuKebab.Title);
list.Items.ShouldContain(m => m.Title == TestData.MenuKotelet.Title);
}
}
Here is the error message:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 5.0.8)
[xUnit.net 00:00:00.88] Discovering: OrderManagement.Application.Tests
[xUnit.net 00:00:00.95] Discovered: OrderManagement.Application.Tests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.3+1b45f5407b (64-bit .NET 5.0.8)
[xUnit.net 00:00:00.87] Starting: OrderManagement.Application.Tests
The active test run was aborted. Reason: Test host process crashed : Stack overflow.
at Autofac.Util.Disposable.get_IsDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
at Autofac.Core.Lifetime.LifetimeScope.IsTreeDisposed()
However the service works fine with the swagger. Any ideas? I want to be able to run some of my tests as the host admin and some as a tenant admin/user
To change the current tenant id, you can use the ICurrentTenant.Change
method. (https://docs.abp.io/en/abp/4.4/Multi-Tenancy#change-the-current-tenant)
You need to use this approach in your tests, (https://github.com/abpframework/abp/blob/dev/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureChecker_Tests.cs#L25-L28)
For host admin you need to pass the
tenantId
as null.
using (_currentTenant.Change(tenantId))
{
//your test logic
}