2015-08-17 1 views
3

En C# Je l'habitude d'écrireA.CallTo (...). ReturnsLazily (...) throws "L'objet spécifié n'est pas reconnu comme un faux objet."

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

pour capturer les appels à Fetch().

Quand j'ai essayé la même chose avec F #

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

le test échoue avec

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) 
... 

Il ressemble à F #, il doit être défini un peu différemment. Avez-vous une idée de comment?

+0

Je ne suis pas un F # perso n, mais j'essayais d'écrire F #, et je l'ai eu. Je me disais, "quel type fait' fun() => provider.Fetch' "résoudre à? Pour que FakeItEasy fonctionne, il devrait être l'équivalent d'une expression > '. –

+0

Je ne suis pas une personne FakeItEasy, mais si FakeItEasy dépend de l'analyse ou de la réflexion sur des expressions lambda, alors vous n'avez pas de chance. Les fonctions F # ne sont pas des expressions lambda dans le sens où vous pouvez les manipuler en utilisant l'API d'expression C#, malgré une syntaxe similaire. – scrwtp

Répondre

6

FakeItEasy utilise des expressions LINQ, qui sont prises en charge dans F # 3, mais il semble y avoir une incompatibilité lors de l'utilisation de l'API statique. Basé sur le message d'erreur "objet n'est pas reconnu comme un faux objet" Je soupçonne que dans ce cas, la résolution de l'objet est C#/VB.Net spécifique.

membre de l'instance de FakeItEasy de configuration basée sur ne semble cependant travailler:

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

Une autre option consiste à utiliser F # et Moq (ici j'utilise le Moq.FSharp.Extensions):

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

Ou bien Foq , qui a été conçu spécifiquement pour F #:

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