forki / NaturalSpec

NaturalSpec
Other
82 stars 16 forks source link

Removed Mock Features? #1

Open ChrisMarinos opened 14 years ago

ChrisMarinos commented 14 years ago

It took me way too long to start playing around with this, but it looks like the project has a TON of potential as an all in one testing solution for F#.

I'm a big fan of MOQ for my C# code, but it won't work in F# without some extra ugliness as it relies on Linq Expressions. One of the things that finally made me start playing around with NaturalSpec was the clean syntax for mocking that you used to support. It fit my needs perfectly, but it looks like it was removed about a month ago. Is this just to avoid a dependency on Rhino.Mocks, or is there something else in the works?

Either way, I'd like to propose supporting the old syntax (or something similar) since the mocking features that replaced it don't meet my needs. I'd be happy to help implement these features, and I'd rather work with similar goals instead of diverging.

Let me know what your thoughts are.

-Chris

forki commented 14 years ago

Hi Chirs,

I think we can do this, but my idea was to use handcrafted mocks via object expressions. For the future I want to support Moles from http://research.microsoft.com/en-us/projects/pex/downloads.aspx. What do you think of Moles?

Regards, Steffen

ChrisMarinos commented 14 years ago

Steffen-

I hadn't heard about moles until now. My initial response is that it looks like a cool project, but I'd have to play around with it more to say for sure what I think about it. The ability to re-wire static functions is nice. TypeMock is the only other mocking library that I have heard can do that (I have never used TypeMock, though). Also, I suspect the license might be a problem for some folks.

I'm not a fan of mocking using object expressions because I think you end up re-implementing a lot of things that mocking frameworks provide. They work in the simple case, but they're a pain for interfaces with many members. I'll try to get a blog post out with a more complete argument.

-Chris

ChrisMarinos commented 14 years ago

Steffen-

As promised, my "more complete" argument :-)

http://chrismarinos.com/f-object-expressions-vs-mocking-libraries-am-i-missing-something/

-Chris

ChrisMarinos commented 14 years ago

Steffen-

I'm sorry that I took so long for me to get back to you on this. I'm finally getting back to a somewhat normal schedule after a hectic month. As promised, here are some thoughts on the new mocking syntax.

-I'm not sure I like the syntax for mocking properties. MOQ, my favorite C# mocking library, uses a value when mocking a property instead of a function. For NaturalSpec, that would look like:

mock<IFoo> "MyMock"
|> registerProperty <@fun x -> x.Name @> "MyName"

instead of

mock<IFoo> "MyMock"
|> registerProperty <@fun x -> x.Name @> (fun _ -> "MyName")

Using a function is more powerful if you want to do something nasty like return a mutable variable that you modify later in the test, but I'm not sure that it's a good thing. It's also less intuitive.

-It doesn't look like I can mock interfaces that have methods with generic arguments. This was a dealbreaker for my use case.

-I don't see the value in giving the mock a name. Typically, saying "given an object with interface X mocked" is enough for me. It's often more than one interface, too.

-I like the way your syntax gives me the ability to mock out function behaviors. In many cases, I just need to mock out return values based on input, though. I'd like to see additional syntax similar to the following:

type IFoo =
    abstract Foo: int -> int

mock<IFooTwo> "foo"
|> When <@fun x -> x.Foo 1 @> 2
|> When <@fun x -> x.Foo 3 @> 4

If I have time, I may try to implement some of this and send you a pull request. We'll see how my schedule looks!

Either way, thanks for all of your hard work on this library!

-Chris

forki commented 14 years ago

Hi Chris,

thanks for your feedback.

Mocking values is much easier than mocking functions. We could add another "register" function:

let registerPropertyValue propertyQuote value = registerProperty propertyQuote (fun _ -> value)

It doesn't look like I can mock interfaces that have methods with generic arguments.

At the moment NaturalSpec can only mock very few cases (e.g. no abstract class) - it just a prototype.

I don't see the value in giving the mock a name.

That's just for the report feature. One could add another mock function which uses a default name. But sometimes we may want to use something like personas in our scenarios.

Regards, Steffen