Default return value callback (validating feature request)

Nov 20, 2013 at 11:48 AM
We use Foq via AutoFixture.AutoFoq.

For interfaces, AutoFoq creates a Mock<IX>() for every object.

As covered in other issues, the default return value for mocked methods is null.

AutoFixture affords us a general way of adjusting strategies for creation of specimen objects to be used within our tests. (Mentioning this as it may be less of a Good Idea from an Opinionated API perspective to do what I'm suggesting in the absence of an ability to manage the return values in an appropriate manner)

Right now, I have a customization like the following:
 type ACustomization() = 
    interface ICustomization with
        member this.Customize fixture =
            fixture.Register<AClient>(fun () -> 
                Mock<AClient>.With( fun x ->
                <@
                    x.ListAvailable( any(), any()) ---> fun () -> fixture.Create()
                    x.Lock( any(), any(), any(), any()) ---> fun () -> fixture.Create()
                @>))
For a wide variety of tests, this means I can either have some default stuff returned (in the above the fixture.Create() returns a set of 3 randomly generated items appropriate to the type concerned.

If Foq was to offer a way to pass in a System.Type -> obj, I could connect that to a lower level API within AutoFixture which is an untyped equivalent of the fixture.Create() above.

It's important for the control to be on a per-Mock basis (the specific fixture is the vector for customizations of the exact return value).

If you think this is a good idea, it'd be nice to see at some stage (even if only in Foq 2).

No major reason to rush as obviously for most sane interfaces, doing a With() is a) concise b) safe

If you think having a global magic return value mechanism for Mocks is a Bad Idea, I'm open to that (A bit like the way I'm very dubious about having a verifyAll mechanism)
Coordinator
Nov 20, 2013 at 12:15 PM
Edited Nov 20, 2013 at 12:22 PM
Just to check I'm understanding this right, what you'd like to do is something like:
x.ListAvailable( any(), any()) --?> fun t -> fixture.Create(t)
x.Lock( any(), any(), any(), any()) --?> fun t -> fixture.Create(t)
where t is the return type and fixture.Create(t) return obj?

and then the lambdas could be replaced with:
let autoGenerate t = fixture.Create(t)

x.ListAvailable( any(), any()) --?> autoGenerate
x.Lock( any(), any(), any(), any()) --?> autoGenerate
or something at setup like:
Mock<AClient>(returnStrategy: fun t -> fixture.Create(t))
Nov 20, 2013 at 1:38 PM
Edited Nov 20, 2013 at 1:40 PM
HI Phil, Thanks for your [more than fair to say usual] responsiveness -- and sorry for then going off on a 48 minutes after drive-by posting as I'm wont to do :(

Re your autoGenerate proposal, I believe the existing support is fine for that sort of thing, i.e
let autoGenerate () = fixture.Create

x.ListAvailable( any(), any()) ---> autoGenerate
x.Lock( any(), any(), any(), any()) ---> autoGenerate
should resolve that as AutoFixture and Foq are both fully typed ion all the right places (i.e. the return type of the ---> operand and the fixture.Create method). Arguably the .Method mechanism might have a corner case where this form of control would be necessitated, in which case it would prove invaluable.

Yes, I am talking about your final syntax. For pedants, the exact syntax in AF will prob be:
Mock<AClient>(returnStrategy: new SpecimenContext(fixture).Resolve)
Peeping at the source and the other issue it would seem the code is in good shape to facilitate this -- though I'll hold off on attempting even a spike impl :D

BTW, care to share any feelings on whether this is actually a good idea for a Mocking lib ?

Side note, AutoMapper causes something in this direction a Custom Value Resolver
Coordinator
Nov 20, 2013 at 4:36 PM
Yes, this shouldn't be particularly hard to implement, it should only require a few hooks in the code.

I think that this may also be useful for a number of other use cases I had planned, so I'll try and add it in for 1.4 which I'm planning to release in a couple of weeks, it should be available from source much sooner.

Cheers!
Nov 20, 2013 at 11:14 PM
Edited Nov 20, 2013 at 11:15 PM
Wonderful. As mentioned, I'm in no big rush but it will definitely add delight far out of proportion with the number of lines of code I get to actually delete (mainly due to AF keeping me pretty DRY in my _Arrange_s).

ASIDE:

I'll be interested to see whether Nikos or Mark have any views as to whether to either bake support into AutoFoqCustomization as a default (prob not as it's a breaking change), offer it as a built-in Customization (AutoFoqSynthesizeReturnValuesCustomization ? :P) or some other form of easily-opt-innable thing.

I guess with idiomatic AF usage, it's no biggie to have to add a line of code to a codebase into one's AutoData hierarchy - it's mainly a matter of taste/opinion (but hopefully something more reasoned!) whether synthesizing results from mocked methods as a default thing to do is a good idea.
Nov 21, 2013 at 11:25 AM
FWIW, in AutoFixture.AutoMoq a mocked instance is post-processed using an ISpecimenBuilder decorator named MockPostprocessor.

In the future, we could move to a similar direction with Foq too :)
Nov 21, 2013 at 12:03 PM
Hi Nikos,

Not sure what you're saying; it's extremely likely I'm missing your point.

While Foq supports something similar to mock.DefaultValue setting, I'm wanting to have a different way of controlling it. I'm requesting/proposing/describing an API which:
a) doesnt require 'mutation' of the mock
b) requires an extra arg to be passed to the Mock<T> constructor

That style would seem to make a postprocessor a lot less relevant?

My questions / atting is regarding whether instead of requesting that return values be generated by the Mock / null depending on the DefaultValue setting, AutoFoqCustomization would go the whole way and wire in fixture.Create as a the value generator (and whether that would be both good and sustainable)
Nov 21, 2013 at 1:23 PM
Edited Nov 21, 2013 at 1:24 PM
Hi Ruben

Oh, I see... If you don't want to mutate the mock you can always define a strategy for selecting the appropriate Mock<'T> overload.

The strategy for selecting the appropriate method or constructor is defined by the IMethodQuery interface. Actually, something similar is already done in AutoFoqCustomization using the FoqMethodQuery strategy.

So, when the new syntax is available in Foq you could be able to pack all this into a Customization by using a custom IMethodQuery implementation.

Hope that helps :)
Nov 21, 2013 at 1:42 PM
Yes - def looks like using it won't be a big deal in a temp fork impl. Nothing new in thee remainder of this para for you here, just confirming my understanding:-
  1. if you look at http://foq.codeplex.com/SourceControl/changeset/66f71cb3c6db you'll see Mock<'T> is about to grow a returnStrategy param on some overload
  2. FoqMethod (or a parallel impl) can collaborate with FoqMethodQuery to pass fixture.Create down the chain in some cases.
My main question is whether AutoFixture.AutoFoq should have such a customization (and/or whether then existing one simply grows a way to pass a returnStrategy and/or wire it to fixture.Create pretty close to the surface of the API.

I personally find it useful to be able to build CustomizeAttributes [for params] and/or use [<Frozen>] to influence the return values not via the mocking setup but instead through AF customizations.

I'm interested to know people's opinions on whether this is a good idea/they [would] use such a style. If there was a general interest and/it was useful, I'd be requesting that AutoFoq switch from a policy of getting Foq to return nulls to instead returning the proceeds of fixture.Create (as opposed to going the route of getting Foq to return a mocked result a la what you showed to AutoMoq does (and/or can be told not to do)
Nov 23, 2013 at 10:49 AM
It should be possible to create such a customization. Here is an example.
Nov 23, 2013 at 10:31 PM
Nice work.

Any thoughts on whether default AutoFoqCustomization should switch to doing this OOTB - i.e. is returning nulls as it does now a better default?

Amirite that AutoMoq configures recursive Moqs OOTB? What to the other Auto* wirings do?

I think I would like this to be a default and can't think of any significant downsides (esp as the recursive mocks in Foq wouldnt be mutable and via AutoFixture you could achieve many desirable effects by Customizeing the return value). Or am I missing something?
Nov 24, 2013 at 9:51 AM
While the existing behaviour of AutoFixture.AutoFoq supports optional constructor arguments if the mocked type is a class, is it common to also implicitly setup all members?
Nov 24, 2013 at 9:48 PM
Edited Nov 24, 2013 at 9:49 PM
is it common to also implicitly setup all members
Not sure I can parse this to determine what you mean -
  • is it common to want it
  • is it common to explicitly do it
  • are there common patterns/established conventions that would benefit from such a mechanism/strategy
Regardless of which angle you mean, it depends to a significant degree on whether you're trying to Mock or Stub I guess (don't have xUTP beside this machine to expand unecessarily :D).

Turning the question around, which is the best choice in general for a method that's not explicitly mocked:
  1. Constrained non-determinism
  2. throw NotConfiguredException
  3. return null
  4. return a mock if its an interface or abstract and/or some other criteria and otherwise return default(T)
For AutoMoq, I believe it's #4, for AutoFoq I believe it's #3.

I'm putting forward my feeling that the default OOTb should be #1 unless
  1. someone can explain the reasoning behind the AutoMoq default (esp wrt value types being default(T) unlike the rest of AF specimens) and/or
  2. we map that to something appropriate to AutoFoq
In the case of AutoMoq, one could be doing a Mock.Get()... to configure the Mock in some way. In the absence of the mutation facility in Foq, you're left with verifying on a nested mock. I'd consider that to be straying into Law of Demeter violation territory (having said that I've simply never encountered a case where it seemed to solve a problem - I might just be missing some valuable concept).

I very commonly want the collaborators to return something rather than a null return value that I may or may not have added handling for yet. Generally, you end up debugging your test -- its a POLA violation.

In some recent work I've been trying to adhere to Mocks for Commands, Stubs for queries. I feel that having Constrained nondeterminism in the absence of specific setups is in line with how the rest of AF behaves.

The bottom line is,if it's deemed bad for some styles of tests to not have a setup for everything necessary, I'd prefer my testing infrastructure to shout about the problem rather than hand me nulls. (See also this [now-implemented] Feature request which informs my thinking somewhat.

Obviously this is getting way off-topic for here. If you can give me an idea of
a) whether you think AutoMoq's default is ideal
b) if you do, what you think would be appropriate/idiomatic for AutoFoq given Foq doesnt allow setups to be mutated
c) whether there is a larger problem/discussion that we should get more input on or whether you feel it's just me looking at testing from a particular angle that's not demonstrably shared (by anyone?!)
... I'll formulate either a discussion issue or one or more AutoFoq feature requests with the aim of getting AF-relative input
Nov 25, 2013 at 3:27 PM
Oh, with common I meant that most of the scenarios require a Mock or a Stub with explicit setup or a Dummy. These scenarios are already covered by the existing auto-mocking glue libraries...

AFAICT, the proposed Customization generates a Test Double that falls into the Dummy/Stub territory – It would be passed as a parameter value when required and instead of hard-coded data it returns constrained non-deterministic data generated by AutoFixture's equivalence classes. (Hence my question about whether it is common or not.)

For properties, it could be doable with all the auto-mocking glue libraries (e.g.: Here is how to automatically populate properties with AutoMoq).

For methods, while Foq now accepts a Strategy for members (including methods) that have not been explicitly setup, I am not sure if the other mocking tools supports that (or a similar hook during mock object construction).

Right now the constrained non-deterministic behaviour for Stubs can be packed into a Customization (e.g.: AutoFoqSynthesizeReturnValuesCustomization).

In case of proposing it as the default behaviour in AutoFixture 4, it would be great to continue the rest of the discussion there :)
Nov 27, 2013 at 8:22 AM
A feature like
Mock<AClient>(returnStrategy: new SpecimenContext(fixture).Resolve)
is an idea I had a couple of months ago myself, so obviously, I think it's a splendid idea.

From AutoFixture's perspective, an even better signature for the return strategy would be obj -> obj, but since Type -> obj is a special case, that would also work.
Nov 27, 2013 at 1:32 PM
Edited Nov 27, 2013 at 10:31 PM
Thanks for the response Mark.

Foq 1.4 on NuGet has a returnStrategy: Type->obj parameter implemented (Not sure what you mean to be honest, I can't figure out what Foq could ever need to Resolve other than a Type. If you have a clear purpose for it, I'd venture that now is a good time [for considering a 'breaking change' (as a bugfix to 1.4) if it's useful enough]

Some follow-on questions which I'd like to have squashed or flagged as worthy of raising as AutoFixture issues:

The OOTB behavior of AutoFoq is to generate a default Mock<T> at the moment. I think it's not a useful default as Foq Mocks :
1) are not mutable [via a mechanism such as Moq's Mock.Get()] (unless I'm mistaken) so any setup work forced to Inject an explicitly-generated Mock via an ICustomization if you want to influence it
2) return nulls [Unless you flip the static global default of Foq which I assume others would find distasteful too]

I have a suite of tests (say 50ish) using AutoFoq and based on my experience so far, the existing AutoFoq behavior could safely be replaced by Mocks with a returnStrategy wired to AutoFixture.

I know this has all gone TL;DR as is my wont but I'm trying to ensure I only pollute this discussion with that as opposed to me foisting a similarly unfocused issue(set) over on github/AutoFixture.

I don't want to propose this until we can get clear opinions/votes (but ideally soundly argued reasons) regarding a better default behavior that isnt a bad idea.

My ideal AutoFoqCustomization behavior (ordered) is:
  1. Constrained non-determinism as just explained - I believe this to be idiomatic AutoFixture [and a Golden hammer :)]
  2. throw NoReturnConfiguredException (see this implemented recent Foq feature request) to avoid any surprises - I believe this to be less a POLA violation than nulls [and its nice that it meshes with sensible usage of Foq for F# values]
  3. return null (i.e. current AutoFoq behavior) - for me: a) surprising as AutoMoq doesnt do that b) not useful c) not what Foq will do in F# w/o AutoFoq [which is more or less #2: throws if nulls are not allowed for the return Type]
  4. return a mock if its an interface or abstract and/or some other criteria and otherwise return default(T) (i.e. try to match AutoMoq) - this doesn't make sense for me as Foq Mocks' Setups are not mutable (but admittedly if you told Foq to generate a Recursive Moq, you could do deep verifications which might be useful?)
I'd like to know which of each of the above others think
a) are useful
b) are a good idea
c) should be the default for AutoFoq

If I can get enough response here, I can use it to decide what (if any) issues to post on GitHub.com/AutoFixture

EDIT: NB I'm in no rush with this - Nikos has furnished us with a POC impl and I personally am presently doing Mock.With ... fixture.Create() wirings by hand so don't especially need it to be in AutoFoq at present (but I do believe AutoFoq's default is not appropriate - But I guess depending on how strongly one feels and/or views the above that's either a bug or a breaking change that should wait for V4)
Nov 29, 2013 at 2:31 PM
Edited Dec 12, 2013 at 12:55 PM
@NikosBaxevanis @ptrelford I've applied Foq 1.4 and Nikos' gist to replace AutoFoqCustomization with 40 production tests (mostly new tests, new SUTs but some hairy collaborators for some integration tests).

I'm very happy firstly with Nikos and Phil's great work on the impls (ditto Don, Mark, Jim and Brad and others) - AutoFixture.xUnit and AutoFixture.AutoFoq in F# is amazing - type inference, Mock.With and AutoFixture.xunit together remove so much crap compared to doing the same thing in C#

I can't really think of any negatives and will continue to recommend it for serious consideration as the new default behavior of AutoFoqCustomization. I'll be watching out for cases where I find it's a bad default and try to keep them synced here.

Things I ran into:
  1. Was able to throw away some Forced mocking in favour of the new 'recursive behavior':
type TimerFactoryCustomization() = 
    interface ICustomization with
        member this.Customize fixture =
            let timing = Mock<Timing>().Create()
            let timerFactory = 
                Mock<ITimerFactory>
                    .Method( fun x -> <@ x.Create @>).Returns( timing )
            fixture.Inject( timerFactory)
(I wouldnt be surprised if Foq has a more direct method - main point is the default behavior Just Works which is great)

Result: yay!
  1. Need a mechanism a la AutoFixture.AutoMoq + AutoFixture.xUnit's ability to let me automate my sprinking of the following snippet [via a customization] to force mocking of a concrete classes:

    fixture.Inject( Mock<AllocationServiceClient>( SpecimenContext(fixture).Resolve).Create())
In AutoFixture.xUnit with AutoMoq I could have said fixture.Freeze<Mock<AllocationServiceClient>>

@NikosBaxevanis Any ideas how this can be accomplished cleanly with AutoFoq?

Result: Have workaround (see ForceMockingCustomization below)
  1. The fact that I hadnt wired the returnStrategy in the Mock<T>.With( callchain <strike>doesnt allow passing a returnStrategy</strike> caused a surprise [to me] reversion to returning 'null' from unmentioned methods. As it happens, <strike>I was happy with the final result (I was setting up 2 mockings: one where the return value needed to be an explicit value and another where it had to be non-null (to avoid an NRE)</strike>I'm still slightly on the fence as to what the best returnStrategy is when .With has configured some -- I'm thinking it should throw now. I had a larger With statement that had 3 mockings which was hiding this dependency and being able to delete that brought it to light.
Result: In this (single) case specifying all the required mocking is great. I'd have been less surprised if my AutoFixture-based returnStrategy had been in place (but the best solution of all would might be for .With to plug in a "You didnt tell us what to return for this call" exception (UPDATE: Need to investigate if Foq exposes a pre-built return strategy that should be used to do this assuming there isn't a consensus on having a different policy). For clarity, I'm talking about a helper:
type MockWithAttribute<'T when 'T : not struct>( mockSetup :IFixture -> 'T -> Quotations.Expr<unit>) = 
    inherit CustomizeParamAttribute<'T>( fun fixture -> 
        fixture.Inject( Mock<'T>.With( fixture |> mockSetup, SpecimenContext( fixture).Resolve )))
which one uses as follows:
type HasDataAttribute() = 
    inherit MockWithAttribute<IRepository>( fun fixture x -> <@ x.HasData() --> true @>)

type Facts = 
    [<Theory; AutoData>] 
    let ``When repo has data Should yield Some`` ([<HasData>]repo:IRepository) (sut:ISutty) = 
        ()
  1. Four tests started failing due to changed behavior of the AutoFoq-generated Mock of an abstract class which I generally supply a TypeRelay for. (A method which with the current AutoFoqCustomization returns default(bool) started to return true
Result: I became aware of a mocking I wasn't consciously aware of. I was happy to do put in an explicit setup to return false instead.
Result: I realized 1 test had an implicit setup which I had been lazy and not added which would have made the test very difficult to understand
Result: I realized CanInstantiateSut test was reliant on lots of coincidences relating to the default(T) return values. This made me realize that I should have a more/less 1:1 relationship between AutoDataAttribute classes and tests to verify they are wired correctly. In other words, good too
  1. I have the following helper types. Time will tell if some of them are useful to have in AutoFoq (@NikosBaxevanis I'd be happy to talk you through them over Chrome RDP if you're interested)
open Foq
open Ploeh.AutoFixture
open Ploeh.AutoFixture.Xunit
open Ploeh.AutoFixture.Kernel

[<AutoOpen>]
module AutoDataHelpers =
    let applyCustomization (fixture:IFixture) customization  = 
        fixture.Customize( customization) |> ignore 
    let instantiateCustomization (customizationType:Type) = 
        Activator.CreateInstance( customizationType) 
            :?> ICustomization

[<AutoOpen>]
module AutoFoqHelpers =
    let private resolveType fixture = SpecimenContext( fixture).Resolve
    let autoFoqWith<'T when 'T : not struct> mockSetup (fixture:IFixture) = 
        Mock<'T>.With( mockSetup, resolveType fixture)
    let autoFoqMock<'T when 'T : not struct> fixture = 
       Mock<'T>( fixture |> resolveType)
    let autoFoqMockCreate<'T when 'T : not struct> fixture = 
       autoFoqMock<'T>( fixture).Create()

type AutoFoqDataAttribute() as this = 
    inherit AutoDataAttribute()
    let customize (customization:ICustomization) = applyCustomization this.Fixture customization
    do customize <| AutoFoqFork.AutoFoqSynthesizeReturnValuesCustomization()  // TODO move to AutoFoqCustomization should this become the default 
    member this.Customize c = customize c
    member this.CustomizeByType t = customize <| instantiateCustomization t

type MockWithCustomization<'T when 'T : not struct>( mockSetup:'T -> IFixture -> Quotations.Expr<unit>) = 
    interface ICustomization with
        member this.Customize fixture =
            fixture.Inject( autoFoqWith (fun x -> fixture |> mockSetup x) fixture)
    new( mockSetup:'T -> Quotations.Expr<unit>) =
        MockWithCustomization( fun x (_:IFixture) -> mockSetup x)

type ForceMockingCustomization<'T when 'T : not struct>() =   
    interface ICustomization with
        member this.Customize fixture =
            fixture.Inject <| autoFoqMockCreate<'T> fixture

type BindCustomization<'I, 'T>() = // TODO when 'T :> 'I // No can do: http://stackoverflow.com/questions/3857474/how-to-constrain-one-type-parameter-by-another
    interface ICustomization with
        member this.Customize fixture =
            fixture.Customizations.Add( TypeRelay( typeof<'I>, typeof<'T>))

[<AbstractClass>]
type CustomizeAttribute<'T>( customize) = 
    inherit CustomizeAttribute()
    override this.GetCustomization pi =
        if typeof<'T> <> pi.ParameterType then 
            let message = sprintf "Invalid attempt to apply a CustomizeAttribute intended to be applied to a parameter of type %s to %s instead." typeof<'T>.Name pi.ParameterType.Name
            invalidArg "parameterType" message
        { new ICustomization with member __.Customize fixture = customize fixture }

type MockWithCustomizeAttribute<'T when 'T : not struct>( mockSetup:'T -> Quotations.Expr<unit>) = 
    inherit CustomizeAttribute<'T>( fun fixture ->
        fixture.Customize <| MockWithCustomization( mockSetup) |> ignore)
Coordinator
Nov 29, 2013 at 2:58 PM
@bartelink glad it worked :) and has helped reduce some boilerplate, thanks for the suggestion and feedback.

Mock.With does now have an optional returnStrategy as the second argument (didn't want to break the API).

Cheers!
Nov 29, 2013 at 4:16 PM
Edited Nov 29, 2013 at 10:48 PM
@ptrelford Thanks for the [usual!] quick response. Yes, I was too lazy (the bad kind of lazy!) to consider that you'd have thought of that and look in the obvious place.

I've applied it and the code reduction of 10 lines (out of 450 lines in my suite) from being able to express my .Withs as one-liners has persuaded me that having a returnStrategy on With was in fact pretty important)

I've edited in the implications to my preceding post.

Wow - that's a lot of discarded toxic brackets, parentheses and types :)
Nov 30, 2013 at 9:07 AM
Thanks a lot for all the great feedback!

Some first thoughts:

If you want to use fixture.Freeze<Mock<AllocationServiceClient>> with Foq's upcoming return strategy you need to customize the Fixture instance with a decorator:
fixture.Customizations.Add(
  FoqPostprocessor(
      MethodInvoker(
          FoqSynthesizeReturnValuesMethodQuery(fixture))))
The hypothetical FoqPostprocessor should create a mock with the new return strategy (hence the injection of the FoqSynthesizeReturnValuesMethodQuery class).

I haven't tried (yet) to implement a FoqPostprocessor, but the complete implementation of the AutoFoqSynthesizeReturnValuesCustomization should also include this behaviour :)
Dec 1, 2013 at 10:54 AM
FWIW, since the remaining of the discussion is related only to AutoFixture.AutoFoq, I opened an issue in AutoFixture project site so we may discuss further there.

I haven't yet seen all the great helper types, in the second half of the feedback, but I think that once we pack the new behavior into a customization a few of them (e.g.: ForceMockingCustomization) might not be needed :)
Dec 2, 2013 at 3:31 AM
Thanks for raising the issue - I agree with its scope and wording.

If the standard Freeze<Mock<T>> effect can be achieved that's would be wonderful (it never occurred to me that it wold work with Foq due to lack of mutability but because I didnt consider the possibility due to the normal call chains being either Mock.With( ... ) or Mock<T>()... .Create() i.e. it doesnt really feel like there is a single clear thing to freeze for me to even consider the possibility. As I say though, if a signalling via freezing something in Mock<T> isn't possible / natural, perhaps a new technique may be needed (hopefully not).

(I don't particularly see where a postprocessor would fit in - the returnStrategy has either been passed to the ctor (or Mock.With( returnStrategy: )) or not at the point of creation. It's v likely this is due to me reading too much into what you are saying or my lack of familiarity of the impl techniques of the AF.A* libs and/or the exact meaning of the term Postprocessor; I'm babbling about this here rather than on the issue itself as I'm v comfortable assuming it's me that's confused!)

Re my customizations, while they all satisfy Rule of 3 reqs, its hard to say which merit consideration for broader use and/or consideration in either Core / an AutoContrib or AutoFoq. Here are some general notes:-
  1. CustomizeParamAttribute: a real impl should just throw an argexception rather than my assertion abuse. I feel it is useful and arguably should be in core.
  2. MockWithAttribute's fixture param is currently not required by the bulk of the usages but where it is used it's obv critical. I'm fairly certain it's proved it's worth in brevity in general (and given how wiring in the returnStrategy is now pretty critical I think the issue impl should include something similar [if not identical]
  3. BindCustomization is tentatively named after Ninjects equivalent op. I'm confident it's useful as I have abuse Register in preference to looking up the syntax for a TypeRelay. Not sure whether a real name should refer to TypeRelay or whether there's a better name that refers to e.g. an xUnit Test Patterns name and/or an AF arch term. Obv the where TImpl : TInterface constraint is pretty critical (even if I have yet to work out eaxactly how to say that in F# :D)
  4. UseFactoryMethodCustomization is inspired by a colleague @adamjasinski - he's far more rigorous than I about applying correct mechanisms. I personally have written more than one unnecessarily brittle fixture.Register<...>( SutType.Create) sequences due to not being able to remember the syntax. I feel this should be in Core as it's pretty common and gives a name to a concept that I feel lots of people currently misapply other techniques for and hence would/should use
  5. We also have a MockSetupAttribute which allows one to supply a Mock<T> -> Mock<T> which supplies the returnStategy and calls .Create() at the end. While Mock<T>.With() is generally the 80% case for us to date, I feel if there was to be a MockWithAttribute its important to also have a MockSetupAttribute for ease of discovery of concepts for people who browse exposed Types in an Api. While a MockMethod might be appropriate on the basis of consistently wrapping all top level methods for symmetry, I personally have yet to find a use for it though obv some .Calls() sequences may benefit from the lack of needing to slug lots of any(), any() .... chainings. Not sure whether the best compromise is to have a single MockedAttribute<T> which then lets one call either .Method [without any .Create() being needed] or do a Setup()....Setup()....Create() and let users create a derived class as desired.
  6. The purpose of AutoFoqDataAttribute / AutoDataHelpers is to allow clean impl of derived classes as follows :
type AutoXXXDataAttribute() as this = 
    inherit AutoFoqDataAttribute()
    do this.Customize <| MyXXXCustomization()
    do this.Customize <| MyYYYCustomization()
This can save a lot of mess around the ignore requirement for the customize and/or drilling into base / base.Fixture. Not sure whether the CustomizeByType / instantiateCustomization stuff is a) broadly applicable - we only have 2 usages so far b) a good idea (I thing being forced to create and [intention revealingly] name an AutoDataAttribute class and/or CompositeFixture is prob still a good policy). Having said that being able to say [<AutoXXXData*(typeof<AdjustTheFrobOnTheSutsInnerFlapCustomization>)] can be very useful. The cleanest syntax I've managed to produce is:
type AutoYYYDataAttribute( customizationTypeOption) as this = 
    inherit AutoFoqDataAttribute()
    do 
        this.Customize <| YYYCustomization()
        Option.iter this.CustomizeByType customizationTypeOption 
    new( t) = AutoYYYDataAttribute( Some t)
    new() = AutoYYYDataAttribute( None)
There are plently subtleties to [obv the naming as per usual and] whether the Type-based stuff should be an overload of the hackneyed Customize name (and whether the line Option.iter this.CustomizeByType customizationTypeOption can/should be expressed in a different way.