0

I am mocked the UserStore and userManager and getting User by userManager method FindByIdAsync Correctly but when I send That User and one claim to AddClaim Function Its Giving me null value. Here Is my Unit Test Setup and test In Which I am setting parameter for account Repository for Example UserManager, SignInManager.

```

       
        var _userManager = new Mock<UserManager<ApplicationUser>>(mockUserStore.Object, null, null, null, null, null, null, null, null);
        
[SetUp]
        public void Setup()
        {
            options = new DbContextOptionsBuilder<ApplicationDbContext>()
             .UseInMemoryDatabase(databaseName: "TestDbOR247")
             .Options;
            context = new ApplicationDbContext(options);
            ApplicationUser userNew = new ApplicationUser()
            {
                Cvr = 12345678,
                IsBusiness = true,
                CustomerNumber = 0,
                Type = 0
            };
            userNew.IsBusiness = true;
            userNew.Email = "I@gmail.com";
            userNew.UserName = "Ikram@123";
            userNew.Id = userId.ToString();
            var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
        var _signInManager = new Mock<SignInManager<ApplicationUser>>(_userManager.Object, Mock.Of<IHttpContextAccessor>(), Mock.Of<IUserClaimsPrincipalFactory<ApplicationUser>>(), null, null, null, null);
        var roleStore = new Mock<IRoleStore<IdentityRole>>();
        var _roleManager= new Mock<RoleManager<IdentityRole>>(
                     roleStore.Object, null, null, null, null);
        var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
        mockHttpContextAccessor.Setup(o => o.HttpContext.User).Returns(It.IsAny<ClaimsPrincipal>());
        //_accountRepository = new AccountRepository(context,_signInManager.Object,_userManager.Object,_roleManager.Object,mockHttpContextAccessor.Object);

        _accountRepository = new Mock<AccountRepository>(context, _signInManager.Object, _userManager.Object, _roleManager.Object, mockHttpContextAccessor.Object);
        //mockUserStore.Setup(x => x.FindByIdAsync(userId.ToString(), CancellationToken.None))
        //.ReturnsAsync(new ApplicationUser()
        //{
        //    UserName = "I@gmail.com",
        //    Id = userId.ToString()
        //});

        _userManager.Setup(x => x.FindByIdAsync(userId.ToString()))
        .ReturnsAsync(new ApplicationUser()
        {
            UserName = "I@gmail.com",
            Id = userId.ToString()
        });

        var data = context.AppUsers.ToList();
        if(data.Count==0)
        {
            AddSampleDataIntoDatabase();
        }
        var data1 = context.Users.FirstOrDefault();
        applicationUser = data1;
        var list=_accountRepository.Object.FindUserById(userId.ToString()).Result;
        Console.WriteLine("Testing list should be application user");
        var accountMock = new Mock<IAccountRepository>();
        //auto mapper configuration
        var mockMapper = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new ApplicationMapper());
        });
        var mapper = mockMapper.CreateMapper();

        //Claim List
        accountService = new AccountService(_accountRepository.Object);
    }
```

Here Is My Unit Test in Which I am calling to service which is using account repository

[Test]
        public async Task AddClaim_UserNotNull_ReturnTrue()
        {
            var user1 =await accountService.FindUserById(userId.ToString());
            Console.WriteLine("users1 Should be Application user so I can Pass it to AddClaim method");
            var claimList = ClaimList();
            //Act
            var result = await accountService.AddClaim(applicationUser, claimList[1]);
            //Assert
            Assert.That(result, Is.True);
        }

Here Is My Method In Repository and Claim List

public async Task<bool> AddClaim(ApplicationUser user, Claim claim)
        {
            var result=await _userManager.AddClaimAsync(user, claim);
            if (result.Succeeded)
                return true;
            else 
                return false;
        }

public List<Claim> ClaimList()
        {
            string claimType = "";
            string claimValue = "true";
            List<Claim> claims = new List<Claim>();
            foreach (var appClaim in Enum.GetValues(typeof(ClaimTypesUser)))
            {
                claimType = $"{userId}_{appClaim}";
                //await userManager.AddClaimAsync(user, new Claim(claimType, claimValue));
                claims.Add(new Claim(claimType, claimValue));
            };
            return claims;
        }
IkramK
  • 3
  • 2

1 Answers1

0

If the method you are mocking returns null, it often means that the method was not mocked correctly and is returning null by default.

Your code snippets are difficult to follow, but from the code you have provided it looks like you have not mocked the correct method. Your AddClaim() method makes a call to _userManager.AddClaimAsnyc(), but this method is never mocked.

public async Task<bool> AddClaim(ApplicationUser user, Claim claim)
{
    // _usermanager.AddClaimAsync is not SetUp in your test and will return null
    var result=await _userManager.AddClaimAsync(user, claim);
    if (result.Succeeded)
        return true;
    else 
        return false;
}

If you want to mock a return value for this method you need to set it up in your test.

_userManager.SetUp(a => a.AddClaimAsync(It.IsAny<ApplicationUser>(), It.IsAny<(Claim)>)).ReturnsAsync(result)
IanSoc
  • 238
  • 1
  • 3
  • 14
  • Now I am setting up userManager.AddToClaimAsync but still its value is null. – IkramK Nov 02 '22 at 08:46
  • @ikramk ok well the same answer applies. If you are correctly injecting your mock user manager object and AddClaimAsync is returning null when you debug true, then that method is not setup correctly. It's very hard to give specifics though, your code and example is quite hard to follow. I would suggest removing all code except your test, the method being tested and the setup code needed to test that method only. Remove everything that is not needed to test that method and it should make the issue easier to narrow down. – IanSoc Nov 02 '22 at 17:26