c# - MVP、WinForms、单元测试、起订量、NUnit : Verify that event handlers have been added to a dependency

标签 c# winforms unit-testing moq mvp

我有演示者、 View 和模型。 View 不知道演示者。 Presenter 协调一切并仅通过界面了解 View :

public interface ISuspiciousListManagementView
{

    void ShowMessageBox(MessageBoxButtons messageBoxButtons, string message, string caption, EMessageBoxIcons icon);

    void ShowDialog(IWin32Window owner);
    object AllTypesDataSource { get; set; }
    SuspiciousListType SelectedType { get; set; }
    event EventHandler SelectedTypeChanged;
    string FilePath { get; set; }

    bool ShowOnlyActive { get; set; }
    object AllHistoryAvailableTypesDataSource { get; set; }
    SuspiciousFilteredListType SelectedHistoryType { get; set; }
    event EventHandler SelectedHistoryTypeChanged;

    object HistoryDataGridSource { get; set; }

    event EventHandler SelectedShowOnlyActiveChanged;

    ICommand BrowseFileCommand { get; set; }
    ICommand UploadCommand { get; set; }
    ICommand RefreshCommand { get; set; }

}

Presenter 持有方法 Init:

 public async Task Init()
    {
        _view.AllTypesDataSource = Enum.GetValues(typeof(SuspiciousListType));
        _view.AllHistoryAvailableTypesDataSource = Enum.GetValues(typeof(SuspiciousFilteredListType));
        _view.SelectedTypeChanged += OnSelectedTypeChanged;
        _view.SelectedHistoryTypeChanged += OnSelectedHistoryTypeChanged;
        _view.SelectedShowOnlyActiveChanged += OnSelectedShowOnlyActiveChanged;
        _view.HistoryDataGridSource = await GetFilterHistoryItems();
    }

和字段:

  private readonly ISuspiciousListManagementView _view;

这是通过构造函数注入(inject)的。

我需要验证这些代码行是否已运行:

    _view.SelectedTypeChanged += OnSelectedTypeChanged;
    _view.SelectedHistoryTypeChanged += OnSelectedHistoryTypeChanged;
    _view.SelectedShowOnlyActiveChanged += OnSelectedShowOnlyActiveChanged;

我想运行类似的东西:

 [Test]
    public async void Presenter_Verify_HistoryDataGridSource_assigned_Test()
    {
        await _presenter.Init();
       _viewMock.Verify(dp => dp.SelectedHistoryTypeChanged != null);//Compilation error
    }

如何测试事件处理程序是否已添加? 我的设计有什么问题吗?

提前感谢您的帮助。

最佳答案

如果是“自动”事件,如下所示:

class Test {
    public event Action MyEvent;
}

可以通过反射获取调用列表:

var eventField = test.GetType().GetField(nameof(test.MyEvent), BindingFlags.Instance | BindingFlags.NonPublic);
var eventDelegate = eventField.GetValue(test);
//either get invocation list or just compare eventDelegate with null
var invocationList = eventDelegate != null ? ((Delegate)eventDelegate).GetInvocationList() : new Delegate[0];
bool anySubscribers = invocationList.Length > 0;

这是因为编译器将 MyEvent 扩展为(非常粗略地):

class Test {
    private Action MyEvent;

    public event Action MyEvent
    {
        add { Delegate.Combine(this.MyEvent, (Delegate) value);}
        remove { Delegate.Remove(this.MyEvent, value); }
    }
}

我们可以获得该私有(private)(编译器生成)字段的值。

如果事件被显式实现:

class Test {        
    public event Action MyEvent
    {
        add
        {
            // do something

        }
        remove
        {
            // do something else                
        }
    }
}

您不能这样做,因为可能甚至不是订阅者的概念 - addremove 可以执行任意操作。但这很可能不是你的情况。

关于c# - MVP、WinForms、单元测试、起订量、NUnit : Verify that event handlers have been added to a dependency,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42763668/

相关文章:

c# - 当无法序列化枚举时,尽早失败或明确抛出

c# - 三元条件下的隐式转换问题

c# - 在 C# Winforms 上验证文本框的输入

c# - 代码应该进行单元测试还是集成测试

c# - 如何从 Awesomium 网页控件复制 Html?

c# - 如何为 Redlock.Net 启用日志记录?

c# - 如何防止在加载表单时检查 RadioButton?

C# SqlCeException : One Line SQL to determine table exists

php - Symfony2 中数据库测试的实践?如何隔离?

java - 用 Spock 模拟 "blocking"方法调用?