- ABP Framework version: v3.0.4
- UI type: Angular
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): no / yes
- Exception message and stack trace: N.A
- Steps to reproduce the issue: N.A
Hi,
I have do some code change in IdentityUserAppService, IdentityRoleAppService and ProfileAppService by overridding few methods. Now I want to do Unit Testing of the overridden methods, How do I do it ? Difficulty facing while writing Unit Testing :
- While overridding I haven't created any Interface for my OverriddenAppService class, So in constructor if I user this code block
_userAppService = GetRequiredService<IIdentityUserAppService>();
this means I am refering toIIdentityUserAppService
Methods not my overridden methods right ? - I have created few custom stuff i.e. if my role say some AnchorAdmin roles logges in user can see only user with same Roles etc. etc. The main problem is how do I seed my testing db with the user details I am playing around with, and then how do I log in with different users to fetch customized data.
In short In my code block I have to fake my login with a particular user as my method have this kind code : For example as below :
public virtual async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
{
var user = new IdentityUser(
GuidGenerator.Create(),
input.UserName,
input.Email,
CurrentTenant.Id
);
if (logged in with user : xyz@abc.com) //then only I have to map extra properties other wise I dont have to map it
{
input.MapExtraPropertiesTo(user);
}
(await UserManager.CreateAsync(user, input.Password)).CheckErrors();
await UpdateUserByInput(user, input);
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user);
}
So in order to test this kind of code I have to create a session where my xyz@abc.com
user is logged in, then and then only I can check my code block right ?
Please help !!!
8 Answer(s)
-
0
Hi @lalitChougule
The
class XAppService
is just an implementation ofinterface IXAppService
, so when you override the implementation (class) you should also replace the implementation ofinterface IXAppService
to yourOverriddenAppService
. Please see this documentation.When you resolve
IXAppService
, the Dependency Injection should useOverridenAppService
instead of default implementation.After that, there is no problem to use
GetRequiredService<IIdentityUserAppService>();
in tests and everywhere. -
0
Hi @cotur,
I will try that. Please provide me solution for my second point as well.
User cases :
I have 2 users (user_1 and user_2), when I log with user_1 and create another user I check if my user is created by user_1 then I have some different action/code to be executed, and if my user_2 login I have to perform different action/code.This is just an example, but I hope u got my point.
Basic Requirement in Unit Test
I need to know how to I write test case where my user_1 is logged in and where my user_2 is logged in. And how do I seed IdentityUser i.e. AbpUsers table in test env with user_1 and user_2 details because as what I have learned there are more than one tables are involved as below:
- AbpUsers
- AbpUserRoles
- AbpRoles
etc etc How to I seed the above tables with my data.
Thanks
-
0
There should be
FakeCurrentPrincipalAccessor.cs
file in yourTestBase
project, we use it to mock user.Also for data seeding, please check this documentation: https://docs.abp.io/en/abp/latest/Testing#the-seed-data
-
0
There should be
FakeCurrentPrincipalAccessor.cs
file in yourTestBase
project, we use it to mock user.Also for data seeding, please check this documentation: https://docs.abp.io/en/abp/latest/Testing#the-seed-data
I got it GetPrincipal() method, but it has main admin. How do I use it in my case. I need to create more than 3-4 Unit test where each method have different login user with different case.
[Fact] public async CheckForUser_1() { using(user_1 logged in) { //my code } } [Fact] public async CheckForUser_2() { using(user_2 logged in) { //my code } } [Fact] public async CheckForUser_3() { using(user_3 logged in) { //my code } } [Fact] public async CheckForUser_4() { using(user_4 logged in) { //my code } }
So where I have used
using(user_1 logged in )
how can I use the method you mentioned ? -
0
You can use
ICurrentPrincipalAccessor
service to change users.The
FakeCurrentPrincipalAccessor
that I mentioned before is also implementsICurrentPrincipalAccessor
First, inject the
ICurrentPrincipalAccessor
in your test classpublic class MyTest : MyTestBase { private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor; public MyTest() { _currentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>(); } }
Then use
Change
method withusing
statement to set new user.[Fact] public async CheckForUser_4() { var user_4 = new ClaimsPrincipal(); using (_currentPrincipalAccessor.Change(user_4)) { // here, the current user will be user_4 } }
-
0
Hi cotur,
I was partially achieve your solution. But I have hit a dead end while seeding Roles
My Code :
public class IdentityRolesDataSeedContributor : IDataSeedContributor, ITransientDependency { private readonly IRepository<IdentityRole> _identityRoleRepository; public IdentityRolesDataSeedContributor(IRepository<IdentityRole> identityRoleRepository) { _identityRoleRepository = identityRoleRepository; } public async Task SeedAsync(DataSeedContext context) { await _identityRoleRepository.InsertAsync(new IdentityRole( id: Guid.Parse("60353FF7-0F81-4DD5-AC1F-6F9559037720"), name: "RoleAbc", tenantId: Guid.Parse("d1be844b-d3a2-031a-f036-39f5d4380239"))); } }
Error while unit testing :
---------- Starting test run ---------- [xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.2+2d84eb3141 (64-bit .NET Core 3.1.13) [xUnit.net 00:00:02.63] Starting: SCV.Litmus.Application.Tests [xUnit.net 00:00:15.39] SCV.Litmus.LitmusIdentity.LitmusIdentityUserApplicationTests.CreateAsync [FAIL] [xUnit.net 00:00:15.39] System.InvalidOperationException : Role ROLEABC does not exist! [xUnit.net 00:00:15.39] Stack Trace: [xUnit.net 00:00:15.39] at Volo.Abp.Identity.IdentityUserStore.AddToRoleAsync(IdentityUser user, String normalizedRoleName, CancellationToken cancellationToken) [xUnit.net 00:00:15.39] at Microsoft.AspNetCore.Identity.UserManager`1.AddToRolesAsync(TUser user, IEnumerable`1 roles) [xUnit.net 00:00:15.39] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) [xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() [xUnit.net 00:00:15.39] at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) [xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) [xUnit.net 00:00:15.39] at Volo.Abp.Identity.IdentityUserManager.SetRolesAsync(IdentityUser user, IEnumerable`1 roleNames) [xUnit.net 00:00:15.39] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) [xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() [xUnit.net 00:00:15.39] at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) [xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) [xUnit.net 00:00:15.39] at Volo.Abp.Identity.IdentityUserAppService.UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input) [xUnit.net 00:00:15.40] D:\Litmus\Projects\ap-ar-dashboard\SCV.Litmus\aspnet-core\modules\litmus-core\src\SCV.Litmus.Application\LitmusIdentity\LitmusIdentityUserAppService.cs(106,0): at SCV.Litmus.LitmusIdentity.LitmusIdentityUserAppService.CreateAsync(IdentityUserCreateDto input) [xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() [xUnit.net 00:00:15.40] at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) [xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() [xUnit.net 00:00:15.40] at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) [xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() [xUnit.net 00:00:15.40] at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) [xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync() [xUnit.net 00:00:15.40] at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) [xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) [xUnit.net 00:00:15.40] D:\Litmus\Projects\ap-ar-dashboard\SCV.Litmus\aspnet-core\modules\litmus-core\test\SCV.Litmus.Application.Tests\LitmusIdentity\LitmusIdentityUserApplicationTests.cs(89,0): at SCV.Litmus.LitmusIdentity.LitmusIdentityUserApplicationTests.CreateAsync() [xUnit.net 00:00:15.40] --- End of stack trace from previous location where exception was thrown --- [xUnit.net 00:00:15.42] Finished: SCV.Litmus.Application.Tests ========== Test run finished: 1 Tests run in 17.2 sec (0 Passed, 1 Failed, 0 Skipped) ==========
Can you tell me what I am doing wrong here ?
-
0
Maybe that's case-sensitive.
await _identityRoleRepository.InsertAsync(new IdentityRole( id: Guid.Parse("60353FF7-0F81-4DD5-AC1F-6F9559037720"), name: "RoleAbc", tenantId: Guid.Parse("d1be844b-d3a2-031a-f036-39f5d4380239")));
System.InvalidOperationException : Role ROLEABC does not exist!
-
0
This question has been automatically marked as stale because it has not had recent activity.