C# 存根一个函数,它回显未知的输入

C# 存根一个函数,它回显未知的输入,c#,unit-testing,rhino-mocks,C#,Unit Testing,Rhino Mocks,我有一个方法,它接受单个方法接口的多个实现,并依次执行它们。每一种都会以某种方式变异ValueType public interface IValueTypeMutator { ValueType ModifyValueType(ValueType valueType); } public class ValueTypeBuilder { public ValueType Create(params IValueTypeMutator[] mutators) {

我有一个方法,它接受单个方法接口的多个实现,并依次执行它们。每一种都会以某种方式变异
ValueType

public interface IValueTypeMutator
{
    ValueType ModifyValueType(ValueType valueType);
}

public class ValueTypeBuilder
{
    public ValueType Create(params IValueTypeMutator[] mutators)
    {
        var valueType = new ValueType { X = "SomeConstant" };

        return mutators.Aggregate(
            (valueType, mutator) => mutator.ModifyValueType(valueType));
    }
}
当我测试使用
ValueTypeBuilder
的类时,每个
IValueTypeMutator
都将是存根。为了在初始化后保持我的
ValueType
的状态,对于一些测试,我希望存根简单地回显
ValueType
输入的值作为返回值

这是必要的,因为没有显式的
Stub()
实现,Stub的默认行为是返回
null
,这将覆盖
Create()
方法前面的
ValueType
初始化。然而,定义
ValueType
初始化中使用的实际值会导致测试变得不必要的脆弱:ValueType的精确初始化与这些特定测试无关,只是保持了它的状态。

符合这里的要求

    _stubMutator = MockRepository<IValueTypeMutator>();
    _stubMutator
        .Stub(x => x.ModifyValueType(Arg<ValueType>.Is.Anything))
        .Do((Func<ValueType, ValueType>) (v => v));
\u stubMutator=MockRepository();
_存根突变器
.Stub(x=>x.ModifyValueType(Arg.Is.Anything))
.Do((Func)(v=>v));

在这种情况下,
ValueType
的精确初始化不是测试的主题,因此我使用了
Arg.Is.Anything
,以确保无论
ValueType
的值如何,都会调用标识函数

我忍不住想雪莉,你实际上可以使用假的或真的
IValueTypeMutator
。使用具体类进行单元测试没有什么错。在这种情况下,我会将
私有类FakeValueTypeMutator
滑入测试类。现在发生的事情要清楚得多

[TestFixture]
public ValueTypeBuilderTest
{
    private class FakeValueTypeMutator : IValueTypeMutator
    {
        public ValueType ModifyValueType(ValueType valueType)
        {
            return valueType;
        }
    }

    //Test code here!
}

我忍不住认为这不再是一个
存根
,而是一个
伪存根
。我不确定
存根
何时变成
伪存根
;让我们假设我们讨论的是Rhino Mock
存根
。我的Rhino Mock
存根
(在实际代码中,它实际上没有前缀为
\u Stub
)在一些测试中也被用作
资产的模拟,因为在Rhino Mock中可以这样做。现在似乎大多数模拟框架也没有区分存根/模拟。在我看来,伪存根和存根的区别在于伪存根是接口或类的工作实现,而存根的使用与文献中的MacGuffin非常相似。在这种情况下,伪代码必须返回类似ValueType的内容。而存根可以并且应该返回null。存根的行为不应该影响测试,但很明显,如果将存根与其他变异子链接,那么就会出现NullException。存根为什么要返回null?而且,正如我所说,我在这里使用的stub这个词完全是这个词的犀牛模仿意义。在其他测试中,我的存根的行为类似于一个模拟,我使用
assertwasall
。仅仅因为我的存根在某种意义上表现得像一个赝品,如果真的是,为什么我要避免使用Rhino模拟存根功能?这是我能想到的Do()最简单的用法之一:标识函数。好吧……也许我不清楚。我并没有使用你们所说的“犀牛模仿词”,因为正如你们所说的,不是你们用什么,而是你们如何使用它。Rhino Mock的Mock在默认情况下适用于模拟测试,其中包括
ExpectWasCalled
。而存根是一个动态对象,只满足测试对它的要求。然而,一个赝品可以用于所有与之相关的测试,因为它是一个工人阶级。存根不满足接口的“代码契约”,而伪存根则满足。这意味着您也应该能够针对伪代码运行单元测试。