我只想处理特定ErrorCode的ManagementException异常,并且在编写单元测试时遇到问题。通常,我会编写测试,以便它类似于以下内容:
Searcher search = MockRepository.GenerateMock<Searcher>();
// wrapper for ManagementObjectSearcher
...
search.Expect(s => s.Get()).Throw(new ManagementException());
...
但是,这并没有将ErrorCode设置为我想要的那个,实际上ManagementException没有设置此值的构造函数。
如何做到这一点?
(请注意,我使用的是RhinoMocks作为我的模拟框架,但我假设这是独立于框架的;我需要知道的是如何创建一个具有特定ErrorCode值的ManagementException。我也发现了一些引用在线使用System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
方法,但这似乎无法公开访问。
答案 0 :(得分:3)
克服这个障碍的最小努力将是一个静态帮助器/实用程序方法,它使用反射来破解所需错误代码中的插槽。使用最优秀的Reflector,我看到有一个私有的“errorCode”字段,它只能通过ManagementException中定义的内部ctors设置。所以:)
public static class EncapsulationBreaker
{
public static ManagementException GetManagementExceptionWithSpecificErrorCode(ManagementStatus statusToBeStuffed)
{
var exception = new ManagementException();
var fieldInfo = exception.GetType().GetField("errorCode",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.DeclaredOnly);
fieldInfo.SetValue(exception, statusToBeStuffed);
return exception;
}
}
验证它有效
[Test]
public void TestGetExceptionWithSpecifiedErrorCode()
{
var e = EncapsulationBreaker.GetManagementExceptionWithSpecificErrorCode(ManagementStatus.BufferTooSmall);
Assert.AreEqual(ManagementStatus.BufferTooSmall, e.ErrorCode);
}
虽然我通常对测试中的反思感到不满,但这是极少数需要/有用的情况之一。
HTH
答案 1 :(得分:1)
从ManagementException派生一个类并使用您自己的隐藏错误代码实现。让你的模拟返回这个课程。
答案 2 :(得分:0)
我会继承ManagementException
并在子类中覆盖ErrorCode
getter(如果正常的保护级别阻止你这样做,也许内省可以让你更接近)。处理ManagementException
但从未听说过您的特定子类的任何代码都应该处理您的子类“就好像”它是您试图为测试目的而模拟的ManagementException
。
编辑:可以想象ErrorCode
无法被覆盖(我讨厌那种严格的语言,他们可以用这种方式停止测试,但不能否认它们存在;-)。在这种情况下,依赖注入仍然可以为您节省 - DI是我最喜欢的测试模式之一。
DI的测试目的是将测试中的代码与可能抑制可测试性的严格假设分离 - 而这正是我们在这里所拥有的,尽管是一种不同寻常的形式。您正在测试的代码当前会执行x.ErrorCode
以获取异常x的错误代码。很好,相反,它必须getErrorCode(x)
,其中getErrorCode
是一个通常只有return x.ErrorCode
的委托;并且它必须具有getErrorCode
委托的setter,以便出于测试目的,您可以将其更改为执行return 23
的委托(或您要模拟用于测试的任何错误代码值)。
细节可以有所不同,但依赖注入可以(除其他外)有助于补偿你不可避免地从系统(或从你无法直接修改的其他库和c)中获得的对象中的某种过度刚性,如此示例
答案 3 :(得分:0)
有一个非常简单的小方法或类来捕获异常并从中获取错误代码,然后将其传递给执行工作的真正类。在测试中,将代码替换为直接传递给实际类,当您获得该错误代码时将通过该代码。
最明显的方法是对异常进行子类化,但是如果这不起作用,那么捕获它的代码会立即抛出你自己的异常,它允许你公开该代码,这将是另一种选择。