我使用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 Weaving)。要提出此异常,一个选项是调用Initialized
方法我不确定是正确的方法吗? (因为数据也可以从其他地方设置为-1。虽然这不是问题,但需要额外的函数调用。)
验证是否使用“a1”参数调用A1,并使用“a2”参数调用A2。
答案 0 :(得分:4)
丹尼尔提出了一个很好的观点,我只是想稍微扩展他的答案。让你测试取决于私有方法调用会创建一个非常脆弱的测试套件。私有方法是实现细节,您应该始终安全地更改内部实现的更改,而不是观察10-20测试的失败。
Initilize
方法的另一点 - 如果很难测试想象你的课程有多难用。罗伯特·马丁在他的一本书中提出了一个很好的观点,即该方法没有说明之前应该调用的其他方法和顺序。
在您的情况下,例如,public void CallA()
没有说明为什么何时以及应该Initialize
调用args的原因。为什么不使用输入参数从Initialize
创建构造函数或从构造函数调用Initialize。现在你确定它已经被调用了。另一点是关于幻数-1
。
很抱歉批评,但我已经使用过这样的设计并且很难测试它们,无论你使用什么测试\模拟框架。你可以模拟private
方法,你可以存根静态方法调用,但这一切都以良好的设计结束,而不是模拟框架的强大功能。
答案 1 :(得分:2)
你做不到。
模拟框架用于模拟要测试的类的依赖关系。模拟类本身是没有意义的,因为它意味着你测试模拟而不是你的类。
此外,验证您的类中的私有方法是否也被调用也是不正确的。您需要验证其他一些方法,两种常见的方法是:
您可以和应该使用哪一个主要取决于您要测试的课程。