单元测试中的序列化异常

时间:2014-06-26 06:52:29

标签: c# .net unit-testing

我的Visual Studio(2010)单元测试遇到了问题。

每当出现任何错误并且抛出一个类型的异常时,UnitTestAdapter抛出SerializationExceptions,告诉我他不能反序化抛出的异常。

在我创建的单元测试中,这些主要是System.Data.SqlServerCe.SqlCeExceptionNHibernate.MappingException

我无法弄清楚为什么会这样。研究告诉我,最常见的原因是UnitTestAdapter无法使用这些类型所在的程序集,但是当我查看TestResults文件夹时,我会看到所需的每个程序集,包括System.Data.SqlServerCe.dll和{{1 }}

那么 - 我该怎么做才能调试呢?我需要在测试结果中看到它们以任何方式有用的例外情况。

2 个答案:

答案 0 :(得分:2)

运行 Visual Studio单元测试时,VSTestHost是初始化并运行测试的过程。

创建新的 AppDomain ,并将 AppDomain 的基本目录设置为单元测试" Out" 包含运行测试所需的所有程序集和依赖项的目录。

测试目录名为" TestResults" ,位于解决方案文件所在的同一目录中。在" TestResults" 目录中,您会发现每个测试运行的一堆子目录。

单元测试完成后,执行线程将返回VSTestHost进程的默认 AppDomain 。返回默认 AppDomain 的部分过程是对其调用上下文中的对象进行反序列化。但是,BaseDirectory已重置回包含VSTestHost可执行文件"C:\Program Files\Microsoft Visual Studio {version}\Common7\IDE"的目录。

这会导致反序列化失败,因为在VSTestHost目录中找不到反序列化的类型。例外情况如下:

单元测试适配器引发异常:成员未解析类型&x; xxx,xxx,版本= 2.0.3370.22002,文化=中性,公共密钥名称=空白'

可能的hack可以在" C:\ Program Files \ Microsoft Visual Studio {version} \ Common7 \ IDE"中创建一个目录。叫" UnitTestAssemblies"。将所有必需的程序集复制到此目录中。然后手动编辑名为" VSTestHost"的VSTestHost.exe.config配置文件。包括作为探测路径的一部分创建的目录:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
 <probing privatePath="PrivateAssemblies;PublicAssemblies;UnitTestAssemblies"/>
</assemblyBinding>

这将强制查找在反序列化期间为任何缺失类型创建的目录。

修改

由于semms是一个程序集绑定问题Iam建议您尝试Assembly Binding Log Viewer (Fuslogvw.exe)来分析资源加载过程,所以我希望您能发现问题的神秘性

答案 1 :(得分:1)

好吧,经过大量的工时浪费,我偶然发现了解决方案。或多或少......

This post向我指出了方向,更具体地说是引用

  

回顾一下,MyCustomException是在测试执行的早期阶段抛出的。包含它的DLL还没有加载,所以Unit Test Adapter确实无法访问它。

我使用自定义基类来初始化需要数据库连接的UnitTests。此基类有正常构造具有ClassInitialize,因为[ClassInitialize] is not called by the UnitTestAdapter when it's in subclasses

public DatabaseAware()
{
    XmlConfigurator.Configure();

    _logger.Info("Configuring NHibernate");
    _configuration = new Configuration().Configure();
    _sessionFactory = _configuration.BuildSessionFactory();
}

因此,在调用构造函数时,如果出现任何问题,所有内容的执行显然都会停止。

奇怪的是,这个包括加载程序集。因此,当我的构造函数抛出异常时,NHibernate的程序集尚未加载,导致Type is not resolved for member NHibernate.HibernateException消息。

真是个好车。基本上,我现在所做的就是在构造函数中引入异常处理,如果出现任何问题就会失败:

public DatabaseAware()
{
    XmlConfigurator.Configure();

    try
    {
        _logger.Info("Configuring NHibernate");
        _configuration = new Configuration().Configure();
        _sessionFactory = _configuration.BuildSessionFactory();
    }
    catch (Exception ex)
    {
        _logger.Fatal(ex);
        Assert.Fail(ex.Message);
    }
}

现在,我可以像以前一样运行测试,没有任何问题。 (或者,至少,当构造函数中出现问题时,我会收到通知)。