C# 带有Fakes的NodaTime抛出TypeInitializationException,但不抛出';没有假货

C# 带有Fakes的NodaTime抛出TypeInitializationException,但不抛出';没有假货,c#,visual-studio,unit-testing,mstest,C#,Visual Studio,Unit Testing,Mstest,我想填充NodaTimeSystemClock.GetCurrentInstant()方法。因此,我在VisualStudio 2017中创建了一个单元测试(2015年也进行了尝试)。我通过Nuget package Explorer将NodeTime包添加到UnitTest项目中。之后,我右键单击NodaTime程序集并按下addfakes程序集 我写了一小段代码,它抛出了一个TypeInitializationException:公共语言运行库检测到一个无效的程序 这给了我以下例外情况: S

我想填充NodaTime
SystemClock.GetCurrentInstant()
方法。因此,我在VisualStudio 2017中创建了一个单元测试(2015年也进行了尝试)。我通过Nuget package Explorer将NodeTime包添加到UnitTest项目中。之后,我右键单击NodaTime程序集并按下addfakes程序集

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

这给了我以下例外情况:

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
System.TypeInitializationException:“TzdbHolder”的类型初始值设定项引发异常。-->System.TypeInitializationException:“DefaultHolder”的类型初始值设定项引发异常。-->System.InvalidProgrameException:公共语言运行库检测到无效程序。
在NodaTime.TimeZones.TzdbZone1970Location..ctor(Int32纬度秒、Int32纵向秒、IEnumerable`1国家、字符串区域ID、字符串注释)
at NodaTime.TimeZones.TzdbZone1970Location.Read(IDateTimeZoneReader阅读器)
在NodaTime.TimeZones.IO.TzdbStreamData.Builder.HandleZone1970LocationsField(TzdbStreamField字段)
在NodaTime.TimeZones.IO.TzdbStreamData.c.b_u24_u6(生成器生成器,TzdbStreamField字段)
在NodaTime.TimeZones.IO.TzdbStreamData.FromStream(Stream-Stream)
在NodaTime.TimeZones.TzdbDateTimeZoneSource.DefaultHolder.LoadDefaultDataSource()处
at NodaTime.TimeZones.TzdbDateTimeZoneSource.DefaultHolder..cctor()
---内部异常堆栈跟踪的结束---
at NodaTime.TimeZones.TzdbDateTimeZoneSource.get_Default()
在NodaTime.DateTimeZoneProviders.TzdbHolder..cctor()处
---内部异常堆栈跟踪的结束---
在NodaTime.DateTimeZoneProviders.get_Tzdb()上
在c:\**snip**\UnitTestProject1\UnitTestProject1\UnitTestProject1\UnitTest1.cs中的UnitTestProject1.UnitTest1.TestMethod1()处:第16行
我调试了NodaTime源代码,它在列表上的foreach循环中出错。当我删除foreach循环时,代码运行良好。当我在int列表上添加foreachloop时(参见下面的代码),异常再次出现

foreach(var i in List<int> {1,2,3}) {}
foreach(列表{1,2,3}中的变量i){
当我将其更改为普通for循环时,异常消失了

var list = new List<int> {1,2,3};
for(var i = 0; i < list.Count; i++) {
    var item = list[i];
}
var list=新列表{1,2,3};
对于(var i=0;i
因此它与
foreach
循环和
列表有关。对于任何感兴趣的人,可以在

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

这不是NodaTime中的一个bug,但我认为这是VisualStudio Test Runner中的一个bug。当我搜索VisualStudio的这种行为时,谷歌说“不”。我还尝试使用Nunit运行测试,结果成功,但在Nunit中无法使用
ShimsContext
:-(

你们知道这里发生了什么吗?在我向微软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的情况下也进行了尝试)
  • NoDaTime2.2.0(NuGet的最新版本,也尝试从GitHub repo编译)

如果您计划在某个时间段进行节点切换,请在您的CSProj中添加:

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

参考:
Nodatime.csproj

如果您计划延长Nodatime,请在您的csproj中添加:

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

参考:
Nodatime.csproj

当我搜索Visual Studio的这种行为时,谷歌说“不”。
这句话是什么意思?“我想填充Nodatime SystemClock.GetCurrentInstant()方法。”你不应该。你应该使用
SystemClock.Instance
为你的生产代码注入
IClock
,使用
NodaTime.Testing中的
FakeClock
为你的测试注入一个
IClock
,这就是它的目的。显然这不应该发生,尽管…@mjwills这是对“计算机说不”的引用换句话说,在谷歌的帮助下,我找不到关于这个问题的任何东西:-)它可能值得包括所有涉及的版本-Visual Studio、.NET、Noda Time、Fakes等。对我来说,使用更难测试的方法似乎很奇怪,即使有可测试的方法可用。只有在自然难以测试的情况下,我才会使用冒牌货之类的侵入性东西。
当我搜索Visual Studio的这种行为时,谷歌说‘不’。
这句话是什么意思?“我想填充NodaTime SystemClock.GetCurrentInstant()方法。”你不应该这样做。您应该使用
SystemClock.Instance
为生产代码注入
IClock
,使用
NodaTime.Testing
为测试注入
FakeClock
——这就是它的用途。显然,这不应该发生,尽管…@mjwills,这是指“计算机说不”。换句话说,在谷歌的帮助下,我找不到关于这个问题的任何东西:-)它可能值得包括所有相关内容的版本-Visual Studio、.NET、Noda Time、Fakes等。对我来说,使用更难测试的方法似乎很奇怪,即使有可测试的方法可用。我只会在自然难以测试的情况下使用冒牌货之类的侵入性东西。