2017-04-24 103 views
3

給定一個具有FSharp樣式函數的接口。NSubstitute和FSharp - 嘲笑FSharp函數

type IUseless = 
    abstract member Listify: string -> int -> string list 

你會如何模擬該功能?

let substitute = NSubstitute.Substitute.For<IUseless>() 
substitute.Listify.Returns(??? what would even go here ???) 

我不指望能嘲笑它像一個包含一個功能正常的方法,或值(儘管這是一個什麼樣它代表排序)。

所以我很好奇,如果有人成功地用典型的.NET模擬庫嘲笑FSharp函數。

回答

6

第一:是的,你完全可以嘲笑這像一個正常的方法:

let substitute = NSubstitute.Substitute.For<IUseless>() 
(substitute.Listify "abc" 5).Returns ["whatevs"] 

這工作,因爲F#編譯此定義,就像一個正常的.NET方法,儘管咖喱語法。這部分是爲了互操作,部分是爲了表現。

但第二:如果我是你,我寧願跳過整個NSubstitute業務完全和使用內聯接口的實現,而不是:

let substitute = { new IUseless with member x.Listify a b = ["whatevs"] } 

這是清潔,更typechecked,很多在運行時快。

+0

同意使用內聯接口實現的建議(通常稱爲[對象表達式](https://fsharpforfunandprofit.com/posts/object-expressions/))。一般來說,當你編寫F#代碼時,你通常不必跳過三十個箍來讓單元測試工作。嘲笑,存根,依賴注入......如果你正在編寫純粹的功能代碼,所有這一切簡化了等式。 Mark Seemann寫了很多關於這個主題的[好博客文章](http://blog.ploeh.dk/tags/#Unit%20Testing-ref)。 – rmunn

+0

如果您使用了'object expressions',那麼您是否必須實現接口的每個成員? –

+0

是的,你會的。這是你不得不縮小界面的原因之一。即使面向對象的人也推薦這樣做。 –