Do定义没有被后续定义覆盖

本文关键字:定义 覆盖 Do | 更新日期: 2023-09-27 17:52:39

void ABC()
{
    var foo = Substitute.For<IFoo>();
    foo.When(x => x.Bar()).Do(x => counter++);
    <use Bar()>.... 1
    foo.When(x => x.Bar()).Do(x => counter--);
    <use Bar()>.... 2
}

对于上面的代码片段,(1)和(2)都显示计数器++行为,表明When…Do行为没有被重写。我需要这种行为来生成我想要连接不同回调的测试场景。

我应该如何做到这一点?

Do定义没有被后续定义覆盖

Do回调不会被替换,但两者都应该执行。例如(使用NSub 1.4.3.0):

var counter = 0;
var sub = Substitute.For<IFoo>();
sub.When(x => x.Bar()).Do(x => counter++);
sub.Bar();
Console.WriteLine(counter);  // prints 1
sub.When(x => x.Bar()).Do(x => counter--);
sub.Bar();
Console.WriteLine(counter);  // prints 1, as counter gets inc'd to 2, then dec'd to 1

我建议少用When..,因为它的使用可能是封装失败的征兆。将行为强制转换为替换对象可以表明我们正在测试的类与依赖类的行为具有深度耦合,而不是我们要替换的接口。

有了这个免责声明,您可以交换回调的一种方法是使用helper类来提供特定的回调:
[Test]
public void Example() {
    var counter = 0;
    var helper = new CallbackHelper();
    helper.Callback = x => counter++;
    var sub = Substitute.For<IFoo>();
    sub.When(x => x.Bar()).Do(x => helper.Callback(x));
    sub.Bar();
    Console.WriteLine(counter);
    helper.Callback = x => counter--;
    sub.Bar();
    Console.WriteLine(counter);
    helper.Callback = x => { counter = (counter+1) * 10; };
    sub.Bar();
    Console.WriteLine(counter);
}
public class CallbackHelper {
    public Action<CallInfo> Callback;
}
/* Prints:
    1
    0
    10
*/

如果你发布了你想要实现的行为交换的具体例子,我们可能会想出一个接口更改来避免使用这个。

希望这对你有帮助。:)