【问题标题】:Rhino mocks how to check if a method was called by another method from the same classRhino 模拟如何检查一个方法是否被同一个类中的另一个方法调用
【发布时间】:2013-02-06 14:24:29
【问题描述】:

我在测试我的一门课程时遇到了一些麻烦。 我有一个抽象类,其中包含一个公共方法和两个受保护的抽象。 我需要测试一次天气公共方法调用的抽象之一。

这是我的代码的示例:

public abstract class A
{
    public string DoSomething(stirng input)
    {
        var output = new StringBuilder();

        foreach (var currentChar in input)
        {
            output.Append(DoSomethingElse(currentChar));
        }

        return output.ToString();
    }

    protected abstract char DoSomethingElse(char charToChange);
}

public class B : A
{
    protected override char DoSomethingElse(char charToChange)
    {
        var changedChar = charToChange;
        // Some logic changing charToChange's value
        return changedChar;
    }
}

因为DoSomethingElse() 受到保护,所以我创建了一个发布该方法的类

public class BPublisher : B
{
    public virtual new char DoSomethingElse()
    {
        return base.DoSomethingElse()
    }
}

我的问题是如何测试 DoSomething() 调用 DoSomethingElse() 的事实 犀牛嘲讽?

附:我曾尝试使用ExpectAssertWasCalled,但没有成功。

【问题讨论】:

    标签: c# unit-testing rhino-mocks


    【解决方案1】:

    您真的需要对此进行测试吗?单元测试应该基于一组输入来测试输出。你如何实现这与测试无关(在输出中你可以包含对象的结果成员/状态)

    例如如果我大量重构您的课程,我仍然希望测试通过。例如如果我给你一个输入,我仍然会得到输出。如果实现不同,我真的不希望测试失败(因为我并不真正关心实现)

    【讨论】:

    • 没错,我确实可以测试A类的输入和输出,但是我已经测试了DoSomethingElse()的工作原理,所以现在我只需要看看它是否正确调用。我不想测试实现我想在DoSomething()中测试DoSomethingElse()的调用
    • 我再次质疑为什么要测试 实现 而不是调用 DoSomething() 时得到的结果
    • 修改了这个例子也许现在更清楚为什么我要测试DoSomethingElse()的调用。
    • @Brian:通常我同意。但是抽象基类有另一种接口:打算被覆盖的虚拟成员。测试基类本身是否调用我的派生类是有意义的。换句话说:期望“输出”的用户不是来自外部的调用者,而是派生类。
    【解决方案2】:

    当您使用new 声明另一个方法时,它与您原来的受保护方法没有任何关系。因为它不是虚拟的,所以你不能模拟它。将其设为虚拟和模拟有点奇怪,因为您派生了一个测试类来创建模拟。

    在这种情况下,我实际上不会尝试使用模拟。为什么不在属性中返回有用的结果?

    public class BPublisher : B
    {
        public readonly StringBuilder chars = new StringBuilder();
    
        public virtual new char DoSomethingElse(char charToChange)
        {
            chars.Append(charToChange);
            return charToChange;
        }
    }
    
    var a = new BPublisher();
    a.DoSomething("abc");
    Assert.AreEqual("abc", a.chars.ToString());
    

    最后还是很奇怪。有时很难测试抽象基类。你也可以考虑将DoSomethingElse公开。

    【讨论】:

    • 检查DoSomething()a.chars.ToString() 的输出是否相等是一个很好的测试。但是假设我决定彻底改变DoSomethingElse() 方法的逻辑,我仍然希望DoSomething() 的测试通过,因为它的逻辑没有改变。
    • 另外例如,如果一个空字符串被发送到DoSomething(),我希望看到DoSomethingElse()根本没有被调用。
    猜你喜欢
    • 1970-01-01
    • 2013-08-02
    • 2016-11-16
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 2014-12-22
    相关资源
    最近更新 更多