[英]Testing with MEF and Moq and NUnit
Shown below are the class and the method in the test class. 下面显示的是测试类中的类和方法。 The test method is for testing during the state that a monitoring request is published. 该测试方法用于在发布监视请求的状态下进行测试。 The expected action is that the handler is called inside the FzrteMonitoringService class. 预期的操作是在FzrteMonitoringService类内部调用该处理程序。
Here, I am trying to verify whether the handler for the monitoringRequestGenerated event is called inside the FzrteMonitoringService class. 在这里,我试图验证是否在FzrteMonitoringService类内部调用了MonitoringRequestGenerated事件的处理程序。 But the problem is that the class Dependency is a dependency, and I trying to figure out how to write the FzrteMonitoringService class to avoid such a dependency. 但是问题在于类Dependency是一个依赖项,我试图弄清楚如何编写FzrteMonitoringService类来避免此类依赖项。 The Dependency class is a class that works with MEF to resolve instances exported with the Export attribute. Dependency类是与MEF一起使用的类,用于解析使用Export属性导出的实例。 An architect was responsible for its design. 一名建筑师负责其设计。 Replacing the Dependency class with a TestDependency class for tests seems like an idea, but how would it create instances? 用TestDependency类替换Dependency类进行测试似乎是一个主意,但是它将如何创建实例呢?
[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));
}
It's not really clear what exactly you're trying to test, looking on a code you've provided, but I'll try to address your question. 根据所提供的代码,目前还不清楚您到底要测试什么,但是我将尝试解决您的问题。
The main problem with Dependency class is that it's static (or probably its Resolve<> method). Dependency类的主要问题是它是静态的(或者可能是它的Resolve <>方法)。 You should try to abstract it via introducing IDependency interface 您应该尝试通过引入IDependency接口来抽象它
public interface IDependency
{
T Resolve<T>();
}
so you can inject it into your service and then mock it in your tests. 因此您可以将其注入服务中,然后在测试中对其进行模拟。 After this simple refactoring your service's constructor will look like this: 经过简单的重构之后,服务的构造函数将如下所示:
[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);
}
and your test: 和您的测试:
[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));
}
Though it may not work properly, but the main idea is there. 尽管它可能无法正常工作,但是主要思想在那里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.