如何使用RhinoMocks测试带有特定参数的方法调用
本文关键字:参数 方法 调用 何使用 RhinoMocks 测试 | 更新日期: 2023-09-27 17:53:46
我使用RhinoMocks进行模拟/存根,使用Nunit框架进行单元测试。
我有以下类
class A
{
private int data = -1;
public void Initialize (int data)
{
this.data = data;
}
public void CallA()
{
if (data == -1) throw new InvalidArgumentException("data has invalid value -1");
try
{
A1("a1");
A2("a2");
}
catch (AException e)
{
throw;
}
catch (Exception e)
{
throw new AException(ErrorCode.UnknownException, e);
}
}
private void A1(string item)
{
}
private void A2(string item)
{
}
}
我正在努力以下测试用例:
InvalidAgrumentException:如果没有调用
Initialized
方法或将-1作为参数传递给Initialized
,则会引发该异常。数据是私有的,所以不能被模拟(除非使用TypeMock isolater之类的库来进行IL编织)。要提出此异常,一种选择是调用Initialized
方法,我不确定这是正确的方法?(因为数据也可以从其他地方设置为-1。虽然这不是问题,但它需要额外的函数调用。验证调用A1时参数为" A1 ",调用A2时参数为" A2 "
Daniel说得很好,我只是想扩展一下他的回答。让您的测试依赖于私有方法调用会创建一个非常脆弱的测试套件。私有方法是实现的细节,你应该总是安全地改变它们,相对于内部实现的变化,而不是观察到10-20个测试失败。
Initilize
方法的另一个要点—如果很难测试,想象一下使用您的类有多困难。罗伯特·马丁在他的一本书中提出了一个很好的观点,这个方法并没有说明其他方法应该以什么顺序被调用。
public void CallA()
没有说明为什么何时调用Initialize
以及使用什么参数。为什么不从Initialize
创建一个带有输入参数的构造函数,或者从构造函数调用Initialize呢?现在你确定它已经被命名了。另一点是关于幻数-1
。
很抱歉批评,但是我曾经使用过这样的设计,并且无论您使用什么测试框架,都很难测试它们。您可以模拟private
方法,您可以存根静态方法调用,但这一切都以良好的设计而告终,而不是模拟框架的力量。
你不能那样做。
mock框架用于模拟你想要测试的类的依赖关系。模拟类本身是没有意义的,因为这意味着你测试的是一个模拟而不是你的类。此外,验证类中的私有方法是否被调用也是不正确的。您需要通过其他方式验证,两种常见的方法是:
- 验证类是否处于正确的状态
- 验证模拟依赖项上的某个方法是否被调用