You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行测试用例Put_IsUnlockUser_ReturnsTrue时BaseController抛出空引用异常

解决测试用例Put_IsUnlockUser_ReturnsTrue中的空引用异常

问题场景

执行测试用例Put_IsUnlockUser_ReturnsTrue时触发空引用异常,相关代码如下:

public class AccountController : BaseController
{
    public ResponseTransferObject Put(AccountPutRequest request)
    {
        if (!string.IsNullOrEmpty(request.UnlockUser))
        {
            if (!Session.RoleName.Equals("Administrator", StringComparison.InvariantCultureIgnoreCase))
            {
                return object; // 此处为语法错误,应返回ResponseTransferObject实例
            }
        }
        // 缺少其他分支的返回逻辑
    }
}

public void Put_IsUnlockUser_ReturnsTrue()  
{  
    AccountController accountController = new AccountController();
    ResponseTransferObject responseTransferObject = new ResponseTransferObject();
    try
    {
        responseTransferObject = accountController.Put(new AccountPutRequest { UnlockUser = "Wind" });
        Assert.IsNotEmpty(responseTransferObject.ToString());
    }
    catch
    {
        Assert.IsTrue(false);      
    }
}

public class BaseController : ApiController
{
    public SessionUser Session { get; set; }

    public BaseController()
    {
        Session = HttpContext.Current.Session["MyUser"] as SessionUser;
    }
}

异常原因

测试环境中不存在真实的HttpContext.Current.Session,因此BaseController构造函数从HttpContext.Current.Session["MyUser"]获取SessionUser时返回null,导致Session属性为空。当AccountController的Put方法访问Session.RoleName时,触发空引用异常。

解决方案

方案1:测试中手动设置Session属性

直接为控制器的Session属性赋值模拟的SessionUser对象,快速解决空引用问题:

public void Put_IsUnlockUser_ReturnsTrue()  
{  
    AccountController accountController = new AccountController();
    // 手动注入模拟的SessionUser,避免空引用
    accountController.Session = new SessionUser { RoleName = "Administrator" };
    ResponseTransferObject responseTransferObject;
    try
    {
        responseTransferObject = accountController.Put(new AccountPutRequest { UnlockUser = "Wind" });
        Assert.IsNotEmpty(responseTransferObject.ToString());
    }
    catch
    {
        Assert.IsTrue(false);      
    }
}

方案2:重构代码,用依赖注入解耦Session

通过构造函数注入SessionUser,消除对HttpContext的直接依赖,让测试更灵活:

修改BaseController和AccountController

public class BaseController : ApiController
{
    public SessionUser Session { get; set; }

    // 构造函数注入SessionUser
    public BaseController(SessionUser sessionUser)
    {
        Session = sessionUser;
    }
}

public class AccountController : BaseController
{
    public AccountController(SessionUser sessionUser) : base(sessionUser)
    {
    }

    public ResponseTransferObject Put(AccountPutRequest request)
    {
        if (!string.IsNullOrEmpty(request.UnlockUser))
        {
            if (!Session.RoleName.Equals("Administrator", StringComparison.InvariantCultureIgnoreCase))
            {
                return new ResponseTransferObject { /* 设置对应属性 */ };
            }
            return new ResponseTransferObject { /* 设置正常逻辑的属性 */ };
        }
        return new ResponseTransferObject { /* 设置UnlockUser为空时的属性 */ };
    }
}

测试用例中注入模拟对象

public void Put_IsUnlockUser_ReturnsTrue()  
{  
    // 创建模拟的SessionUser
    var mockSession = new SessionUser { RoleName = "Administrator" };
    AccountController accountController = new AccountController(mockSession);
    ResponseTransferObject responseTransferObject;
    try
    {
        responseTransferObject = accountController.Put(new AccountPutRequest { UnlockUser = "Wind" });
        Assert.IsNotEmpty(responseTransferObject.ToString());
    }
    catch
    {
        Assert.IsTrue(false);      
    }
}

方案3:用Moq模拟HttpContext(不修改现有代码结构)

如果不想改动原有代码,可以用Moq框架模拟HttpContext和Session:

using Moq;
using System.Web;

public void Put_IsUnlockUser_ReturnsTrue()  
{  
    // 模拟Session并设置MyUser值
    var mockSession = new Mock<HttpSessionStateBase>();
    mockSession.Setup(s => s["MyUser"]).Returns(new SessionUser { RoleName = "Administrator" });

    // 模拟HttpContext并关联Session
    var mockContext = new Mock<HttpContextBase>();
    mockContext.Setup(c => c.Session).Returns(mockSession.Object);

    // 设置当前HttpContext
    HttpContext.Current = mockContext.Object;

    AccountController accountController = new AccountController();
    ResponseTransferObject responseTransferObject;
    try
    {
        responseTransferObject = accountController.Put(new AccountPutRequest { UnlockUser = "Wind" });
        Assert.IsNotEmpty(responseTransferObject.ToString());
    }
    catch
    {
        Assert.IsTrue(false);      
    }
    finally
    {
        // 清理HttpContext,避免影响其他测试
        HttpContext.Current = null;
    }
}

额外提示

原AccountController.Put方法中存在语法错误:return object应替换为具体的ResponseTransferObject实例,同时要补充所有代码分支的返回逻辑,避免编译错误或运行时异常。

内容的提问来源于stack exchange,提问作者Akash Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 04:32:33