使用 MEF、Moq 和 NUnit 进行测试

Testing with MEF and Moq and NUnit

下面显示的是 class 和测试中的方法 class。该测试方法用于在发布监控请求的状态下进行测试。预期的操作是在 FzrteMonitoringService class 内部调用处理程序。

在这里,我试图验证是否在 FzrteMonitoringService class 内部调用了 monitoringRequestGenerated 事件的处理程序。但问题是 class Dependency 是一种依赖,我试图弄清楚如何编写 FzrteMonitoringService class 来避免这种依赖。 Dependency class 是一个 class,它与 MEF 一起使用以解析使用 Export 属性导出的实例。一位建筑师负责其设计。将 Dependency class 替换为 TestDependency class 进行测试似乎是一个想法,但它如何创建实例?

        [ImportingConstructor]
        public FzrteMonitoringService(IEventAggregator inEventAggregator)
        {
            _eventAggregator = inEventAggregator;
            _monitoringRequestExecutor = Dependency.Resolve<IFzrteMonitoringRequestResponseHandler>();
            WatchedPorts = new List<string>();
            FailedAddWatchRequests = new List<MonitoringRequest>();
            _monitoringRequests = new ConcurrentQueue<FzrteMonitoringRequest>();

            //subsription for monitoring requests on the UI thread to limit the user
            //from generating meaningless requests
            _eventAggregator.GetEvent<MonitoringRequestGenerated>()
                .Subscribe(FilterEventType, ThreadOption.UIThread, true);

        }

        [Test]
        [Category("Simple Basic Tests")]
        public void SubscribesToMonitoringRequets_requestPublished_FilterEventTypeCalled()
        {
            //mock of event aggregator and the request event dependencies of monitoring service
            var mockEventAggregator = new Mock<IEventAggregator>();
            var mockMonitoringRequestedEvent = new Mock<MonitoringRequestGenerated>();

            mockEventAggregator.Setup(x => x.GetEvent<MonitoringRequestGenerated>())
                .Returns(mockMonitoringRequestedEvent.Object);

            Action <List<MonitoringRequest>> callbackMethod = null;

            mockMonitoringRequestedEvent.Setup(x => x.Subscribe(
                It.IsAny<Action<List<MonitoringRequest>>>(),
                It.IsAny<ThreadOption>(),
                It.IsAny<bool>(),
                It.IsAny<Predicate<List<MonitoringRequest>>>())).
                Callback<Action<List<MonitoringRequest>>,
                    ThreadOption,
                    bool,
                    Predicate<List<MonitoringRequest>>>((a, t, b, p) => callbackMethod = a);



            var testFzrteMonitoringService = new FzrteMonitoringService(mockEventAggregator.Object);

            //use the actual  event aggregator to publish

            var mockMonitoringRequestEventPayload = new Mock<List<MonitoringRequest>>();
            mockEventAggregator.Object.GetEvent<MonitoringRequestGenerated>().Publish(mockMonitoringRequestEventPayload.Object);

            mockMonitoringRequestedEvent.Verify(x => x.Subscribe(testFzrteMonitoringService.FilterEventType));


        }

查看您提供的代码,我并不清楚您到底要测试什么,但我会尽力解决您的问题。

Dependency class 的主要问题是它是静态的(或者可能是它的 Resolve<> 方法)。你应该尝试通过引入 IDependency 接口来抽象它

public interface IDependency
{
    T Resolve<T>();
}

所以你可以将它注入你的服务,然后在你的测试中模拟它。 在这个简单的重构之后,您服务的构造函数将如下所示:

[ImportingConstructor]
public FzrteMonitoringService(
        IEventAggregator inEventAggregator, 
        IDependency dependency)
{
    _eventAggregator = inEventAggregator;
    _dependency = dependency;

    _monitoringRequestExecutor = dependency.Resolve<IFzrteMonitoringRequestResponseHandler>();
    WatchedPorts = new List<string>();
    _monitoringRequests = new ConcurrentQueue<FzrteMonitoringRequest>();

    //subsription for monitoring requests on the UI thread to limit the user
    //from generating meaningless requests
    _eventAggregator.GetEvent<MonitoringRequestGenerated>()
        .Subscribe(this.FilterEventType, ThreadOption.UIThread, true);
}

和你的测试:

[Test]
[Category("Simple Basic Tests")]
public void SubscribesToMonitoringRequets_requestPublished_FilterEventTypeCalled()
{
    //mock of event aggregator and the request event dependencies of monitoring service
    var mockEventAggregator = new Mock<IEventAggregator>();
    var mockMonitoringRequestedEvent = new Mock<MonitoringRequestGenerated>();
    var mockDependecy = new Mock<IDependency>();

    mockEventAggregator.Setup(x => x.GetEvent<MonitoringRequestGenerated>())
            .Returns(mockMonitoringRequestedEvent.Object);

    Action<List<MonitoringRequest>> callbackMethod = null;

    mockMonitoringRequestedEvent
            .Setup(
                x => x.Subscribe(
                    It.IsAny<Action<List<MonitoringRequest>>>(),
                    It.IsAny<ThreadOption>(),
                    It.IsAny<bool>(),
                    It.IsAny<Predicate<List<MonitoringRequest>>>()))
            .Callback<Action<List<MonitoringRequest>>, ThreadOption, bool, Predicate<List<MonitoringRequest>>>(
                (a, t, b, p) => callbackMethod = a);

    var testFzrteMonitoringService = new FzrteMonitoringService(
            mockEventAggregator.Object, mockDependecy.Object);

    //use the actual  event aggregator to publish

    var mockMonitoringRequestEventPayload = new Mock<List<MonitoringRequest>>();
    mockEventAggregator.Object
            .GetEvent<MonitoringRequestGenerated>()
            .Publish(mockMonitoringRequestEventPayload.Object);

    mockMonitoringRequestedEvent.Verify(
            x => x.Subscribe(testFzrteMonitoringService.FilterEventType));
}

虽然可能不能正常运行,但是大意是有的。