如何使用RhinoMocks测试具有特定参数的方法调用?

时间:2013-01-16 11:14:09

标签: c# unit-testing nunit rhino-mocks

我使用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)
        {
        }

    }

我正在努力跟踪测试用例:

  1. InvalidAgrumentException:如果未调用Initialized方法或将-1作为参数传递给Initialized,则会引发此异常。数据是私有的所以不能被模拟(直到使用TypeMock isolater之类的库IL Weaving)。要提出此异常,一个选项是调用Initialized方法我不确定是正确的方法吗? (因为数据也可以从其他地方设置为-1。虽然这不是问题,但需要额外的函数调用。)

  2. 验证是否使用“a1”参数调用A1,并使用“a2”参数调用A2。

2 个答案:

答案 0 :(得分:4)

丹尼尔提出了一个很好的观点,我只是想稍微扩展他的答案。让你测试取决于私有方法调用会创建一个非常脆弱的测试套件。私有方法是实现细节,您应该始终安全地更改内部实现的更改,而不是观察10-20测试的失败。

Initilize方法的另一点 - 如果很难测试想象你的课程有多难用。罗伯特·马丁在他的一本书中提出了一个很好的观点,即该方法没有说明之前应该调用的其他方法和顺序。

在您的情况下,例如,public void CallA()没有说明为什么何时以及应该Initialize调用args的原因。为什么不使用输入参数从Initialize创建构造函数或从构造函数调用Initialize。现在你确定它已经被调用了。另一点是关于幻数-1

很抱歉批评,但我已经使用过这样的设计并且很难测试它们,无论你使用什么测试\模拟框架。你可以模拟private方法,你可以存根静态方法调用,但这一切都以良好的设计结束,而不是模拟框架的强大功能。

答案 1 :(得分:2)

你做不到。

模拟框架用于模拟要测试的类的依赖关系。模拟类本身是没有意义的,因为它意味着你测试模拟而不是你的类。

此外,验证您的类中的私有方法是否也被调用也是不正确的。您需要验证其他一些方法,两种常见的方法是:

  1. 验证班级是否处于正确状态
  2. 验证是否已调用模拟依赖项上的某个方法
  3. 您可以和应该使用哪一个主要取决于您要测试的课程。