NodaTime with Fakes抛出TypeInitializationException,但没有Fakes

时间:2017-07-26 07:46:21

标签: c# visual-studio unit-testing mstest

我想要修改NodaTime SystemClock.GetCurrentInstant()方法。因此,我在VisualStudio 2017中创建了一个UnitTest(也在2015年尝试过)。我通过Nuget Package Explorer将NodaTime包添加到UnitTest项目中。然后我右键单击NodaTime程序集并按添加假装配

我写了一小段代码,它抛出了一个 TypeInitializationException:公共语言运行时检测到一个无效的程序

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NodaTime;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var a = DateTimeZoneProviders.Tzdb.GetZoneOrNull("Europe/Amsterdam");
        }
    }
}

这给了我以下例外:

System.TypeInitializationException: The type initializer for 'TzdbHolder' threw an exception. ---> System.TypeInitializationException: The type initializer for 'DefaultHolder' threw an exception. ---> System.InvalidProgramException: Common Language Runtime detected an invalid program.
   at NodaTime.TimeZones.TzdbZone1970Location..ctor(Int32 latitudeSeconds, Int32 longitudeSeconds, IEnumerable`1 countries, String zoneId, String comment)
   at NodaTime.TimeZones.TzdbZone1970Location.Read(IDateTimeZoneReader reader)
   at NodaTime.TimeZones.IO.TzdbStreamData.Builder.HandleZone1970LocationsField(TzdbStreamField field)
   at NodaTime.TimeZones.IO.TzdbStreamData.<>c.<.cctor>b__24_6(Builder builder, TzdbStreamField field)
   at NodaTime.TimeZones.IO.TzdbStreamData.FromStream(Stream stream)
   at NodaTime.TimeZones.TzdbDateTimeZoneSource.DefaultHolder.LoadDefaultDataSource()
   at NodaTime.TimeZones.TzdbDateTimeZoneSource.DefaultHolder..cctor()
   --- End of inner exception stack trace ---
   at NodaTime.TimeZones.TzdbDateTimeZoneSource.get_Default()
   at NodaTime.DateTimeZoneProviders.TzdbHolder..cctor()
   --- End of inner exception stack trace ---
   at NodaTime.DateTimeZoneProviders.get_Tzdb()
   at UnitTestProject1.UnitTest1.TestMethod1() in c:\**snip**\UnitTestProject1\UnitTestProject1\UnitTest1.cs:line 16

我调试了NodaTime源代码,它在List上的foreach循环上变坏了。当我删除该foreach循环时,代码运行正常。当我在一个整体列表中添加一个foreachloop(参见下面的代码)时,异常又回来了。

foreach(var i in List<int> {1,2,3}) {}

当我将其更改为正常for循环时,异常消失了。

var list = new List<int> {1,2,3};
for(var i = 0; i < list.Count; i++) {
    var item = list[i];
}

因此它与foreach循环和List有关。对于任何感兴趣的人,可以在NodaTime's GitHub repository

上找到该代码

无论如何,当我删除我在本文开头生成的Fakes程序集时,测试执行并通过。但是,嘿,我想要Shim我之前提到的SystemClock.GetCurrentInstant()方法。

这不是NodaTime中的错误,但我认为这是VisualStudio Test Runner中的一个错误。谷歌说“没有”#39;当我搜索Visual Studio的这种行为时。我也尝试用Nunit运行测试,但是在Nunit中无法使用ShimsContext: - (。

你们知道这里发生了什么吗?在向MSFT VS团队报告之前,只想与您核实。

感谢大家帮助我追踪这个错误。

程序版本:

  • Visual Studio 15.2(26430.15)发行版(企业版)
  • .NET Framework 4.7.02046
  • 假货(Visual Studio 15.2最新发布)
  • Windows 10 Pro 64位(更新至最新版)
  • ReSharper 2017.1.3(在未启用ReSharper的情况下也尝试过)
  • NodaTime 2.2.0(来自NuGet的最新版本,也尝试从GitHub回购中编译)

1 个答案:

答案 0 :(得分:0)

如果您计划分配NodaTime,请添加到您的CSProj:

   <ItemGroup>
    <EmbeddedResource Include="Nodatime\TimeZones\Tzdb.nzd" />
  </ItemGroup>

参考: Nodatime.csproj