繁体   English   中英

C# Moq 验证发布事件给定自定义事件失败 arguments

[英]C# Moq verify publish event failed given custom event arguments

所以我有以下 ViewModel:

using Prism.Commands;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using TrackIt.Model;
using TrackIt.UI.Event;

namespace TrackIt.UI.ViewModel
{
    public class NavigationItemViewModel : ViewModelBase
    {
        private string _displayMember;
        private IEventAggregator _eventAggregator;
        private string _detailViewModelName;

        public NavigationItemViewModel(int id,
            IEventAggregator eventAggregator,
            string detailViewModelName)
        {
            Id = id;
            _detailViewModelName = detailViewModelName;
            OpenDetailViewCommand = new DelegateCommand(OnOpenDetailViewExecute);
            _eventAggregator = eventAggregator;
        }
        public int Id { get; }

        public ICommand OpenDetailViewCommand { get; set; }

        private void OnOpenDetailViewExecute()
        {
            _eventAggregator.GetEvent<TestEvent>()
                        .Publish(Id);
            _eventAggregator.GetEvent<OpenDetailViewEvent>()
                        .Publish(
                new OpenDetailViewEventArgs
                {
                    Id = Id,
                    ViewModelName = _detailViewModelName
                }
                );
        }
    }
}

因此,我在上面有一个ICommand ,它在执行时将触发TestEventOpenDetailViewEvent事件,其中TestEvent具有 integer 参数,而OpenDetailViewEvent具有自定义 class 参数OpenDetailViewEventArgs class。

我正在测试在执行命令时,每个事件的Publish方法都会被调用。 我使用Moq模拟GetEvent调用。 这是我的代码:

using Moq;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TrackIt.UI.Event;
using TrackIt.UI.ViewModel;
using Xunit;

namespace TrackIt.UITests.ViewModel
{
    public class NavigationItemViewModelTests
    {

        [Fact]
        public void ShouldPublishOpenFriendDetailViewEvent()
        {
            const string displayMember = "test string";
            const int id = 4;
            const string detailViewMemberName = nameof(FriendDetailViewModel); // Just take a random detail view

            var _mockedOpenDetailViewEvent = new Mock<OpenDetailViewEvent>();
            var _mockedTestEvent = new Mock<TestEvent>();
            var eventAggregatorMock = new Mock<IEventAggregator>();

            eventAggregatorMock
                .Setup(dp => dp.GetEvent<OpenDetailViewEvent>())
                .Returns(_mockedOpenDetailViewEvent.Object);
            eventAggregatorMock
                .Setup(dp => dp.GetEvent<TestEvent>())
                .Returns(_mockedTestEvent.Object);

            var _itemViewModel = new NavigationItemViewModel(id,
                 displayMember, eventAggregatorMock.Object, detailViewMemberName);

            _itemViewModel.OpenDetailViewCommand.Execute(null);

            _mockedTestEvent.Verify(e => e.Publish(id),
                                                Times.Once);
            _mockedOpenDetailViewEvent.Verify(e => e.Publish(new OpenDetailViewEventArgs { Id = id, ViewModelName = detailViewMemberName }), 
                                                Times.Once);
        }
    }
}

问题是,测试通过了TestEvent事件的Verify ,但OpenDetailViewEvent失败并出现错误Expected invocation on the mock once, but was 0 times ,即使我调试并看到了实际发布的事件。 也许是因为我提供了自定义 class 作为其参数,而TestEvent使用本机 C# class(即int )? 如何解决这个问题?

请改用 参数匹配器,因为在这种情况下实例不能是相同的 object 引用。

// ....
_mockedOpenDetailViewEvent
    .Verify(
        _ => _.Publish(It.Is<OpenDetailViewEventArgs>(arg => arg.Id == id && arg.ViewModelName == detailViewMemberName)),
        Times.Once
    );

It.Is上面用于创建谓词以匹配用于调用成员的参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM