2017-07-26 54 views
0

我想Shim the NodaTime SystemClock.GetCurrentInstant()方法。因此,我在VisualStudio 2017中創建了一個UnitTest(2015年也嘗試過)。我通過Nuget包資源管理器將NodaTime包添加到UnitTest項目中。之後,我在NodaTime組件上點擊右鍵,並按下添加假貨組裝NodaTime與假貨拋出TypeInitializationException,但不是沒有假貨

我寫了一小段代碼,拋出一個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源代碼,它是在一個列表foreach循環變壞。當我刪除該foreach循環時,代碼運行良好。當我在ints列表中添加一個foreachloop時(見下面的代碼),異常又回來了。

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

當我將它改爲正常循環時,異常消失。

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我前面提到的方法。

這不是NodaTime中的錯誤,但我認爲這是VisualStudio Test Runner中的一個錯誤。 Google在搜索Visual Studio的這種行爲時說'不'。我也嘗試與Nunit一起運行測試成功,但在Nunit中無法使用ShimsContext :-(。

你們知道這裏發生了什麼嗎?只是想在我報告之前與你聯繫這給MSFT VS團隊

謝謝大家幫助我跟蹤這個bug

程序版本:

  • 的Visual Studio 15.2(26430.15)發佈(企業版)
  • 的.NET Framework 4.7.02046
  • 假貨(最新隨Visual Studio的15.2)
  • 的Windows 10專業版64位(更新至最新)
  • ReSharper的2017年1月3日(也試過沒有啓用ReSharper的)
  • NodaTime 2.2。0(從最新的NuGet穩定,也試圖從GitHub庫編譯)
+0

'Google在搜索Visual Studio的這種行爲時說'不'。'這句話是什麼意思? – mjwills

+1

「我想Shim the NodaTime SystemClock.GetCurrentInstant()方法。」你不應該。你應該注入一個'IClock',使用'SystemClock.Instance'作爲你的產品代碼,''FakeClock'作爲你的測試''NodaTime.Testing' - 這就是它的用途。顯然這不應該發生,雖然... –

+0

@mjwills它是「計算機說不」的引用http://youtu.be/AJQ3TM-p2QI。換句話說,在Google的幫助下,我找不到任何有關這個問題的信息:-) –

回答

0

如果您打算用叉子叉NodaTime,請添加到您的csproj:

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

參考: Nodatime.csproj