我使用内置的Visual Studio单元测试工具对CRM 2011执行单元测试。很多测试都是断言创建实体。
Assert.IsNull(service.GetFirstOrDefault<Contact>(contact.Id));
(GetFirstOrDefault是一种扩展方法,尝试通过CRM从id检索联系人,如果未找到则返回null)
我想创建我自己的Assert方法,其操作如下:
CrmAssert.Exists(service, contact);
起初我认为从Assert
继承是个好主意,但唉,它是一个静态类。然后我创建了一个新的静态类,如下所示:
public static class AssertCrm
{
public static void Exists<T>(IOrganizationService service, T entity) where T : Entity
{
Exists(service, entity, null, null);
}
public static void Exists<T>(IOrganizationService service, T entity, string message) where T : Entity
{
Exists(service, entity, message, null);
}
public static void Exists<T>(IOrganizationService service, T entity, string message, params object[] parameters) where T: Entity
{
if (service.GetFirstOrDefault<T>(entity.Id) == null)
{
throw new AssertFailedException(message == null ? String.Format(message, parameters));
}
}
}
这样称呼:
AssertCrm.Exists(service, contact);
这很好,除了我真的应该能够设置一次服务,而不是每次都要调用它:
AssertCrm.Service = service;
AssertCrm.Exists(contact);
AssertCrm.Exists(campaign);
AssertCrm.Exists(etc...);
但我相信Visual Studio会尝试运行多线程测试,这意味着当我设置Service
静态属性时,它可以被不同测试中的其他服务覆盖(以及{ {1}}不是线程安全的。
我是否需要使我的AssertCrm类非静态,所以我不必担心多线程?我缺少一种更简单的技术吗?
答案 0 :(得分:0)
您可以将AssertCrm设为单例,然后您可以将其实例化一次,所有其他调用将使用相同的实例。
答案 1 :(得分:0)
我个人更喜欢使用内置断言库的第一个选项。我没有看到你试图用扩展方法或“助手”包装它会带来什么好处。
如果你真的想沿着这条路走下去,你可以在IOrganizationService
上创建一组扩展方法,以消除继续传入它的需要。让它更清洁,但我仍然赞成第一
crmService.AssertExists(contact);
顺便说一下,为什么要在“单元”测试中点击真正的CRM实例?更快,更可维护,以验证测试中的模拟IOrganizationService
。
答案 2 :(得分:0)
经过一些额外的研究后,我没有发现它应该(必须)是一个静态类的任何理由,并且已经将它创建为非静态类。
其他人想要做类似的事情的一个注意事项:为所有实例方法创建静态方法重载,因为ClassName.AssertMethod()
确实在大多数情况下更有意义vs new ClassName().AssertMethod()