我应该使我的自定义单元测试断言类非静态吗?

时间:2013-03-29 14:45:43

标签: c# unit-testing c#-4.0 dynamics-crm-2011 vs-unit-testing-framework

我使用内置的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类非静态,所以我不必担心多线程?我缺少一种更简单的技术吗?

3 个答案:

答案 0 :(得分:0)

您可以将AssertCrm设为单例,然后您可以将其实例化一次,所有其他调用将使用相同的实例。

答案 1 :(得分:0)

我个人更喜欢使用内置断言库的第一个选项。我没有看到你试图用扩展方法或“助手”包装它会带来什么好处。

如果你真的想沿着这条路走下去,你可以在IOrganizationService上创建一组扩展方法,以消除继续传入它的需要。让它更清洁,但我仍然赞成第一

crmService.AssertExists(contact);

顺便说一下,为什么要在“单元”测试中点击真正的CRM实例?更快,更可维护,以验证测试中的模拟IOrganizationService

答案 2 :(得分:0)

经过一些额外的研究后,我没有发现它应该(必须)是一个静态类的任何理由,并且已经将它创建为非静态类。

其他人想要做类似的事情的一个注意事项:为所有实例方法创建静态方法重载,因为ClassName.AssertMethod()确实在大多数情况下更有意义vs new ClassName().AssertMethod()