Getting Session Null during Unit testing

Afaq, Kanwar Muhammad 1 Reputation point
2021-06-16T08:24:17.503+00:00

I am trying to write some unit tests for User Repository CreateUserSession method, in which I set Session for user. When I run the test, I got HttpContext but session object is invalid operation it is failing at this point with a null reference exception. Not entirely sure how to get round this.

Unit Test Method
private readonly User _user;
[Fact]
public void User_should_login()
{
var accessor = Substitute.For<IHttpContextAccessor>();
accessor.HttpContext.Returns(new DefaultHttpContext());

        var fundingPlatformContext = MemoryDbHelper.GetContext();  
       var _unitOfWork = new UnitOfWork(fundingPlatformContext, accessor,  
        new OptionsWrapper<AppSettings>(new AppSettings()));  
        var _contr = new UserController(_unitOfWork);  
          
        //prepare  
  
          
  
        //act  
  
        var loginDto = new LoginDto()  
        {  
            Email = "******@123.de",  
            OrganizationKey = "RB",  
            Password = "123456",  
            UserId = 1  
        };  
        Task<User> result = _unitOfWork.User.CreateUserSession(loginDto);  
  
        //assert  
        Assert.IsType<LoginResponseDto>(result.Result);  
  
        var loginData = (result.Result);  
  
        Assert.NotNull(loginData);  
    }  

User Repository with createUsersession method

public class UserRepository : Repository<User, FundingPlatformContext>, IUserRepository  
{  
  
    private readonly FundingPlatformContext _context;  
    private readonly IHttpContextAccessor _httpContextAccessor;  
    private readonly AppSettings _appSettings;  
  
    public UserRepository(FundingPlatformContext context, IHttpContextAccessor httpContextAccessor, IOptions<AppSettings> appSettings) : base(context)  
    {  
        _context = context;  
        _httpContextAccessor = httpContextAccessor;  
        _appSettings = appSettings.Value;  
    }  
  
      
    public async Task<User> CreateUserSession(LoginDto loginDto)  
    {  
        string error = "";  
        try  
        {  
            string encPwd = EncryptDecryptHelper.Encrypt(loginDto.Password);  
            var userDetail = await _context.Users.Include(q => q.FpUserRoles).ThenInclude(r => r.Roles).Include(o => o.Organization).FirstOrDefaultAsync(e => e.Email == loginDto.Email && e.Organization.OrganizationKey == loginDto.OrganizationKey && e.PasswordHash == encPwd);  
  
            if (userDetail != null)  
            {  
                _httpContextAccessor.HttpContext.Session.SetBoolean("IsLogin", true);  
                _httpContextAccessor.HttpContext.Session.SetId("UserID", userDetail.Id);  
                _httpContextAccessor.HttpContext.Session.SetString("UserName", userDetail.Email);  
                
  
                var tokenHandler = new JwtSecurityTokenHandler();  
                var key = System.Text.Encoding.ASCII.GetBytes(_appSettings.Secret);  
                var tokenDescriptor = new Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor()  
                {  
                    Subject = new ClaimsIdentity(new Claim[] {  
                    new Claim(ClaimTypes.Name, userDetail.FirstName),  
                    new Claim(ClaimTypes.Email, userDetail.Email)  
                }),  
                    Expires = DateTime.UtcNow.AddHours(8),  
                    SigningCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(key), Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature)  
                };  
                var token = tokenHandler.CreateToken(tokenDescriptor);  
                userDetail.PasswordHash = null;  
                userDetail.Token = tokenHandler.WriteToken(token);  
                return userDetail;  
            }  
            else  
            {  
                error = "Invalid user name or password.";  
                return null;  
            }  
        }  
          
        catch (Exception ex)  
        {  
            error = "Error Occurred: " + ex.Message;  
            return null;  
        }  
    }  

Please help me how can I set session so that in CreateUserSession I can set session while unit test

Developer technologies ASP.NET ASP.NET Core
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Duane Arnold 3,216 Reputation points
    2021-06-16T14:19:52.65+00:00

    You're going to have to find a way to mockout HTTPContext.

    https://domburf.medium.com/mocking-the-httpcontext-session-object-in-asp-net-core-2-0-7cda5ec134e

    To me, the code you have presented in not unit testable. It also breaks unit testing rules, becuase it is accessing the database.

    https://www.artima.com/weblogs/viewpost.jsp?thread=126923

    Not all code is unit testable.

    The repository object itself, EF and some other objects within the repository object need to be mocked out in order to run a successful unit test, and I don't think it can be done.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.