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
相关产品推荐
相关产品推荐

