2014-11-15 2 views
0

Я использую метод тестирования NUnit предложил в еще не выпущенной книге «F # Deep Погружения Version 12» (п. 2.2 «Добавление тестов»)Единичное тестирование F # Code Throw Null Reference Исключение, почему?

Приведенный ниже код выполняет отлично составленный или интерактивный с MEMOIZE определяется/не определено. Однако выполнение модульного теста из графического интерфейса NUnit отлично работает с MEMOIZE неопределенным, но с ошибкой «Нулевое ссылочное исключение» при определено значение MEMOIZE. Уведомление memorize() использует Закрытие. Я подозреваю, что исключение происходит, потому что какой-то код инициализации, сгенерированный компилятором, не выполняется, когда NUnit запускается. Как вы думаете?

open System 
open System.Collections.Generic 

open NUnit.Framework 
open FsUnit 

let memoize (f: 'T -> 'U) = 
    let t = new Dictionary<'T, 'U>(HashIdentity.Structural) 
    fun n -> 
     if t.ContainsKey n then t.[n] 
     else let res = f n 
      t.Add(n, res) 
      res 

//TODO: Insure J>0 & K>0 & J<K 
let isMult = 
#if MEMOIZE 
    memoize (fun (j,k) -> k % j = 0) 
#else 
    (fun (j,k) -> k % j = 0) 
#endif 

type ``Given the isMult function``() = 
    [<TestCase(3,1,false)>] 
    [<TestCase(3,2,false)>] 
    [<TestCase(3,3,true)>] 
    [<TestCase(5,10,true)>] 
    [<TestCase(3,15,true)>] 
    [<TestCase(5,13,false)>] 
    [<TestCase(5,15,true)>] 
    member t.``the result is calculated correctly``(j, k, expected) =   
     let actual = isMult (j,k)   
     actual |> should equal expected 

UPDATE:

Автономное приложение NUnit является версия 2.6.3.13283.

«FinnNk» дал мне представление! Я установил пакет Nuget «NUnitTestAdapter». Теперь я могу протестировать непосредственно в VS 2013. Никаких сюрпризов. Я получаю все тесты «зелеными», когда MEMORIZE не определено, и все тесты «красные», когда они определены.

Исключением остается то же самое: «Null Reference Exception». Однако теперь, когда он выполняется в среде IDE, я могу отключить отладчик исключения. Все, что я могу определить, до сих пор в контрольной точке, что она нуждается в символах из:

C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.pdb 

Я установил новый VS 2015 Preview Edition. В этой среде ничего особенного не происходит. Теперь, когда .NET Framework является открытым исходным кодом, возможно, я могу обнулить отладчик именно по проблеме с исходным кодом для «mscorlib».

+0

Мое предположение, что вы компилируете как '.exe', а не' .dll' или что тестовый бегун нарушает некоторые предположения F #. –

+0

Какой бегун вы используете? Для меня в VS2013 с использованием встроенного бегуна или с помощью NUnit GUI runner ваш код работает так, как ожидается, когда я определяю MEMOIZE (я добавил некоторую печать, чтобы убедиться). Бегун Resharper также работает, но тесты появляются дважды, причем половина из них пропускается по какой-то причине. – FinnNk

+0

См. Мое добавление к моему первоначальному сообщению –

ответ

0

Выполняете тесты NUnit в нескольких потоках? Нормальный словарь не является потокобезопасным, так что могут случиться странные вещи. Как насчет использования ConcurrentDictionary, даст ли он тот же результат?

let memoize (f: 'T -> 'U) = 
    let t = System.Collections.Concurrent.ConcurrentDictionary<'T, 'U>() 
    fun n -> t.GetOrAdd(n, f) 
+0

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. - [Из обзора] (/ review/low-quality-posts/13526564) – rptwsthi

+0

У меня было бы, но комментарии не могут содержать многострочный код, не так ли? –