gpt4 book ai didi

c# - 如何防止虚拟方法被模拟?

转载 作者:行者123 更新时间:2023-11-30 16:20:26 25 4
gpt4 key购买 nike

我们有一个基类为 INotifyPropertyChanged 提供了一些默认实现(这个类被许多其他类使用并且不能轻易改变):

public class ObservableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

// this is virtual so derived classes can override it (rarely used, but it is used)
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

现在我有一个接口(interface)和一个派生自 ObservableBase 的抽象基类,并实现该接口(interface)提供一些默认实现(主要用于属性):

public interface INamedTrigger
{
string Name { get; }
void Execute();
}

public abstract class ObservableNamedTriggerBase : ObservableBase, INamedTrigger
{
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; OnPropertyChanged("Name"); }
}

public abstract void Execute();
}

现在我想对 ObservableNamedTriggerBase 的默认实现进行单元测试(使用 NUnit 和 RhinoMocks):

[TestFixture]
public class ObservableNamedTriggerBaseTest
{
[Test]
public void TestNameChangeRaisesPropertyChanged()
{
var prop = "";
var mocks = new MockRepository();
var namedBase = mocks.PartialMock<ObservableNamedTriggerBase>();
namedBase.PropertyChanged += (s, e) => prop = e.PropertyName;
namedBase.Name = "Foo";
Assert.AreEqual("Name", prop);
}
}

不幸的是,这个测试失败了,因为 Rhino 似乎覆盖了 ObservableBase 的虚拟 OnPropertyChanged 方法。

SO questionRhino docs表明 PartialMock 应该完全这样做。另一方面,这个SO question的答案表明 Rhino 总是覆盖虚拟方法,而不管 mock 的类型。

那么文档有错吗?我该如何正确地进行测试?

更新:如果我创建自己的模拟类,只为抽象方法提供虚拟实现,那么测试就会通过,但我想使用 Rhino 模拟来省去执行该操作的工作。

最佳答案

不确定您使用的是哪个版本,但您似乎将 RR(Record-Replay)语法用法与更新的 AAA(Arrange-Act-Assert).基本上,这样做:

var repo = new MockRepository();
var mock = repo.PartialMock<ObservableNamedTriggerBase>();

要求您至少也这样做:

repo.ReplayAll();

缺少它,将导致模拟行为不当(如果您也设置期望/ stub ,则可能需要调用 repo.Record())。考虑到现代语法可用 ( starting with Rhino 3.5 ),这是不必要的努力:

// no repository needed at all
var mock = MockRepository.GeneratePartialMock<ObservableNamedTriggerBase>();

MockRepository 上的新静态方法负责底层的记录重放设置。

关于c# - 如何防止虚拟方法被模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14250575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com