如何防止虚拟方法被嘲笑? [英] How can I prevent virtual methods from being mocked?

查看:114
本文介绍了如何防止虚拟方法被嘲笑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a base class providing some default implementation for INotifyPropertyChanged (this class is used by many other classes and cannot be easily changed):

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));
        }
    }
}

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

Now I have an interface and an abstract base class deriving from ObservableBase and implementing that interface providing some default implementations (mainly for the properties):

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):

Now I want to unit test the default implementations of ObservableNamedTriggerBase (using NUnit and 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似乎覆盖了虚拟 OnPropertyChanged 方法来自 ObservableBase

Unfortunately this test fails as Rhino seems to override the virtual OnPropertyChanged method from ObservableBase.

SO问题犀牛文档表示 PartialMock 应该完全。另一方面,对此 SO问题表明,无论模拟的类型如何,Rhino始终会覆盖虚拟方法。

This SO question and the Rhino docs indicate that PartialMock should exactly not do this. On the other hand the answer to this SO question indicates that Rhino always overrides virtual methods regardless of the type of mock.

那么文档是否错误?以及如何正确测试呢?

So is the documentation wrong? And how do I go about testing this correctly?

更新:如果我创建自己的模拟类,仅为抽象方法提供虚拟实现,则测试通过了,但我想使用Rhino模拟程序来保存完成该工作的工作。

Update: If I create my own mock class providing dummy implementations for just the abstract methods then the test passes but I'd like to use Rhino mocks to save me the work of exactly doing that.

推荐答案

不确定您正在使用的版本,但似乎您正在将RR( Record-Replay )语法用法与最新的AAA( Arrange-Act-Assert )混合使用。基本上是这样:

Not sure which version are you using, but it seems that you're mixing RR (Record-Replay) syntax usage with more recent AAA (Arrange-Act-Assert). Basically, doing this:

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

还需要您至少执行以下操作:

Requires you also to at least do this:

repo.ReplayAll();

缺少这些将导致模拟行为异常(调用 repo。如果您也设置期望/存根,可能需要Record()。考虑到现代语法可用,这是不必要的工作(开头犀牛3.5 ):

Lack of which, will cause mocks to misbehave (a call to repo.Record() might be needed if you're setting expectations/stubbing too). This is unnecessary effort considering modern syntax is available (starting with Rhino 3.5):

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

MockRepository 上的新静态方法正在注意后台的记录重放设置。

New static methods on MockRepository are taking care of the record-replay setup under the hood.

这篇关于如何防止虚拟方法被嘲笑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆