我有一项服务负责订阅EWS以获取新邮件通知。我已经为服务创建了一个接口,以便模拟它并测试一个虚拟实现。但是,每当我试图手动告诉我的事件应该做什么时,我就会碰壁。
这是我的具体实施。
public interface IExchangeService
{
void Subscribe();
}
public class ExchangeServiceSubscriber : IExchangeService
{
private readonly ExchangeService _exchangeService;
private readonly IConsumer<IEmail> _consumer;
public ExchangeServiceSubscriber(
ExchangeService exchangeService,
IConsumer<IEmail> consumer)
{
_exchangeService = exchangeService;
_consumer = consumer;
}
public void Subscribe()
{
// code to subscribe
streamingConnection.OnNotificationEvent += OnEvent;
streamingConnection.Open();
}
public void OnEvent(object sender, NotificationEventArgs args)
{
foreach (NotificationEvent triggeredEvent in args.Events)
{
if (triggeredEvent is ItemEvent)
{
var propertySet = new PropertySet(ItemSchema.UniqueBody, ItemSchema.Attachments)
{
RequestedBodyType = BodyType.Text
};
EmailMessage email = EmailMessage.Bind(args.Subscription.Service,
((ItemEvent)triggeredEvent).ItemId, propertySet);
_consumer.Consume(new ExchangeEmail { Body = email.UniqueBody });
}
}
}
}
不幸的是,EWS中的几乎所有课程都是密封的,或者有一个内部构造函数,这似乎限制了我解耦它们的方式。我试图设置NotificationEventArgs
的期望(例如),但它使用内部构造函数。
以下是我一直在努力的一些想法。您可以阅读有关模拟事件here的信息。
mock.Setup(x => x.OnEvent(new object(), new NotificationEventArgs()));
问题是NotificationEventArgs
使用内部构造函数。
我可以看到这个使用某种包装器,但我不确定它会是什么样子。其中一个重大问题是EWS的制作方式几乎可以防止任何人手动注入依赖关系。我基本上试图测试每当事件OnEvent
触发电子邮件实际消耗的时候。此外,虽然我想测试这个功能,但我不确定它是否值得在每一步都与EWS作斗争。
答案 0 :(得分:3)
让我们先看看你做不到的事情:
NotificationEventArgs
作为子类,因为ctor是内部的。所以基本上,你不能使用“普通方式”创建这个类的实例。我假设您已经检查了工厂方法或类?
这给我们留下了一个选项:使用反射实例化类,例如在Activator.CreateInstance
方法的帮助下:Unit testing exception handling for third party exceptions with internal constructors,如下所示:
mock.Setup(x => x.OnEvent(new object(),
Activator.CreateInstance(typeof(NotificationEventArgs),
BindingFlags.NonPublic | BindingFlags.Instance,
null,
null,
null))
);