我的代码正在使用第三方库,该库在其内部采用单例模式。在第一次访问时,库使用Windows环境变量来标识从中加载它的配置文件夹。
但是,我想在不同的单元测试集中针对不同的文件夹运行。理想情况下,我会为每个单元测试类或某些类指定配置文件夹。
第三方库是一个巨大的对象模型,我的代码只是一组扩展方法。我看不出嘲弄整个图书馆的简单方法。
有没有办法可以为每个测试类创建一个新的appdomain?我知道负载测试有一个在运行测试程序集之间创建域的设置。在我的情况下,这将是很多程序集,我不太确定是否/如何在单元测试testrunner上设置此设置。
或者,我正在考虑购买Typemock Isolator或JustMock,以便我可以使单例返回“null”,从而导致第三方库加载一个新的。我查看了反编译代码,看起来它可以实现所需的结果。当然,那里可能隐藏着更多的“好东西”。
这些是人为的方法。我真正想要的是“刷新”测试,测试类或测试程序集之间的完整appdomain。
当自动化测试需要切换配置文件夹时,我愿意牺牲速度。红绿重构循环可能不包括多个配置文件夹。
有关如何实现这一目标的任何建议吗?
修改 我刚刚发现不同的测试组件会导致单体被擦除。因此,可以根据运行的配置来组织测试程序集,而不是通过测试所针对的依赖项或问题域。
答案 0 :(得分:2)
如果您要进行真正的单元测试(而不是集成测试等),我建议包装外部依赖项。
我看不出嘲弄整个图书馆的简单方法。
看看Facade pattern。你提到它有一个巨大的对象模型;您的代码很可能与其中的一小部分进行交互。考虑使外观声明,因为它的方法描述了你想要完成的而不是如何。外观不一定是通用的,它只需要适合您的应用程序。
确保您的外观实现一个或多个接口。通常,您需要一个或多个工厂返回具体实现的实例。
您的所有其余代码仅使用外观。只能在一个地方调用工厂(或者你可以添加工厂接口);其他一切都是通过Dependency Injection完成的。
要对其余类(除了外观之外的所有类)进行单元测试,您可以注入模拟对象。
您的包装器代码应该是一个非常薄的层。您仍然希望对实际库进行集成测试。
答案 1 :(得分:1)
将单元测试类传播到不同的测试程序集中将导致testrunner创建新的appdomains,因此单例将被删除。 因此,可以根据运行的配置来组织测试程序集,而不是通过测试所针对的依赖项或问题域。
此解决方案可能不适合所有人,原因如下:
这样就有可能通过丰富的测试项目(针对各种测试数据)创建一个混乱的解决方案。由此产生的结构与每个组件和问题域组织单元测试的标准实践相反。
我没有触及单身人士的数据。它只是一个支持数据参考库。单元测试的主要指令是它们不应相互影响或要求特定的顺序。
单元测试的另一个主要指令是它们应该快速运行。幸运的是,我不必在正常的red-> green->重构循环中运行多个测试配置。更大的测试组件套件将是回归测试。