1

我使用 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 隔离器之类的库来执行IL Weaving)。要引发此异常,一种选择是调用Initialized我不确定是否正确的方法?(因为数据也可以从其他地方设置为-1。虽然这不是问题,但需要额外的函数调用。)

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

4

2 回答 2

4

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

方法的另一点Initilize——如果很难测试想象使用你的类有多难。罗伯特马丁在他的一本书中提出了一个很好的观点,该方法没有说明之前应该调用哪些其他方法以及以何种顺序调用。

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

很抱歉批评,但我曾使用过这样的设计,无论您使用什么测试\模拟框架,都很难测试它们。您可以模拟private方法,也可以存根静态方法调用,但这一切都以良好的设计而告终,而不是模拟框架的力量。

于 2013-01-16T11:38:54.840 回答
2

你不能那样做。

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

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

  1. 验证类是否处于正确状态
  2. 验证已调用模拟依赖项上的某个方法

您可以并且应该使用哪一个主要取决于您要测试的类。

于 2013-01-16T11:20:33.737 回答