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

RhinoAutoMocker测试用例因方法属性失败的修复方案咨询

修复StructureMap.AutoMocking中的TypeInitializationException异常

我来帮你拆解下这个问题的根源,以及对应的解决办法:

问题根源

当你用RhinoAutoMocker<IMyInterface>创建mock时,它会通过反射解析接口上的所有成员及其特性,尝试实例化这些特性。你的CustomAttribute继承自ASP.NET的AuthorizeAttribute,这个基类在无ASP.NET运行时上下文的单元测试环境中,很容易因为依赖HttpContext等环境变量,或者特性自身的静态初始化逻辑问题,抛出类型初始化异常。另外,你的CustomAttribute中直接在内部方法里实例化Auth类,虽然这部分是调用时执行,但特性的构造/静态字段初始化(比如TestAuthorizationIsEnabled)如果依赖外部资源,也会触发异常。

具体修复方案

方案1:模拟ASP.NET运行时上下文(针对AuthorizeAttribute依赖)

如果异常是因为AuthorizeAttribute需要ASP.NET上下文,可以在测试初始化阶段模拟必要的上下文对象:

[SetUp]
public void TestSetup()
{
    // 生成HttpContext相关的mock对象
    var httpContextMock = MockRepository.GenerateMock<HttpContextBase>();
    var requestMock = MockRepository.GenerateMock<HttpRequestBase>();
    var responseMock = MockRepository.GenerateMock<HttpResponseBase>();
    
    // 关联mock对象
    httpContextMock.Stub(c => c.Request).Return(requestMock);
    httpContextMock.Stub(c => c.Response).Return(responseMock);
    
    // 设置当前HttpContext
    HttpContext.Current = new HttpContextWrapper(httpContextMock);
}

这样AuthorizeAttribute在初始化时就能找到所需的上下文依赖,避免抛出异常。

方案2:手动创建Mock,绕过AutoMocker的特性解析

如果不需要AutoMocker的自动依赖注入能力,直接手动创建IMyInterface的mock即可,RhinoMocks手动创建mock时不会主动解析并实例化接口上的特性:

[Test]
public void MyInterfaceMethodATest()
{
    // 手动生成mock
    var myInterfaceMock = MockRepository.GenerateMock<IMyInterface>();
    
    // 配置mock行为(比如期望MethodA被调用)
    myInterfaceMock.Expect(x => x.MethodA()).Repeat.Once();
    
    // 执行你的测试逻辑(比如调用依赖IMyInterface的服务)
    // var service = new MyService(myInterfaceMock);
    // service.DoSomething();
    
    // 验证mock的交互
    myInterfaceMock.VerifyAllExpectations();
}

方案3:重构CustomAttribute,移除初始化时的依赖

特性的设计原则是轻量、无副作用,不应该在构造或静态初始化阶段依赖外部资源。你可以重构CustomAttribute:

  • 将授权逻辑(IsAuthorized方法中的Auth实例化)移到单独的服务类中,而非特性内部
  • 让CustomAttribute仅作为标记,授权逻辑由专门的拦截器或过滤器处理
// 重构后的特性仅做标记
public class CustomAttribute : AuthorizeAttribute
{
    // 移除静态字段和内部方法,仅保留必要的标记属性
}

// 单独的授权服务
public class AuthorizationService
{
    public bool IsAuthorized(string name, string roles)
    {
        var auth = new Auth();
        return auth.IsAuthorized(name, roles);
    }
}

这样特性初始化时不会有任何依赖,自然不会抛出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:15:08