2015-08-17 3 views
3

В C# используется для записиA.CallTo (...). ВозвращаетLazily (...) throws «Указанный объект не распознается как поддельный объект».

var provider = A.Fake<ITimeProvider>(); 
A.CallTo(() => provider.Fetch()).ReturnsLazily(call => data[0]); 
container.Register(() => provider); 

для захвата вызовов Fetch().

Когда я попробовал то же самое с F #

let provider = A.Fake<ITimeProvider>() 
A.CallTo(fun() -> provider.Fetch()).ReturnsLazily(fun call -> data.[0]) |> ignore 
container.Register(fun() -> provider) 

тест не пройден с

Test Error : ....Test 
System.ArgumentException : The specified object is not recognized as a fake object. 
at Microsoft.FSharp.Control.AsyncBuilderImpl.commit[a](Result`1 res) 
at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously[a](CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout) 
at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken) 
... 

Это выглядит для F # это должно быть определено несколько иначе. Вы знаете, как?

+0

Я не F # perso n, но я пытался написать F #, и я получил это. Я бы сказал себе: «Какой тип« fun() => provider.Fetch' »разрешен? Для того, чтобы FakeItEasy работал с ним, он должен быть эквивалентом выражения 'Expression >'. –

+0

Я не человек FakeItEasy, но если FakeItEasy зависит от разбора или размышления над лямбда-выражениями, вам не повезло. Функции F # не являются лямбда-выражениями в том смысле, что вы можете ими управлять, используя API-интерфейс выражения C#, несмотря на аналогичный синтаксис. – scrwtp

ответ

6

FakeItEasy использует выражения LINQ, которые поддерживаются в F # 3, однако при использовании статического API существует несовместимость. На основании сообщения об ошибке «объект не распознается как поддельный объект», я подозреваю, что в этом случае разрешение объекта является специфичным для C#/VB.Net.

на основе установки член экземпляра FakeItEasy по тем не менее, по всей видимости работы:

let fake = Fake<ITimeProvider>() 
fake.CallsTo(fun x -> x.Fetch()).ReturnsLazily(fun() -> data.[0]) |> ignore 
let provider = fake.FakedObject 

Другой вариант заключается в использовании F # и Moq (здесь я использую Moq.FSharp.Extensions):

let mock = Mock<ITimeProvider>() 
mock.SetupFunc(fun x -> x.Fetch()).Returns(data.[0]).End 
let provider = mock.Object 

Или же Foq , который был разработан специально для F #:

let provider = 
    Mock<ITimerProvider>.Method(fun x -> <@ x.Fetch @>).Returns(data.[0])