AutoFixture/AutoFixture — pull request #302 by dcastro (2014-08-09 15:59:50+00:00)
Title: AutoMoqBoostCustomization

`AutoMoqBoostCustomization` is a customization that builds on top of AutoMoq's `AutoMoqCustomization`.

`AutoMoqBoostCustomization` uses the existing `MockPostprocessor` to allows mocks to be retrieved from a fixture, and adds its own `MockSetup` to automatically setup mocks created by the post-processor before returning them to the client.

The mock's members (methods/properties/indexers) will be set up in such a way that return values will be retrieved from a fixture (see examples below). Also, if a method contains any "out" parameters, the value for the outcome of these parameters will also be fetched from a fixture.

`MockSetup` is composed by a collection of `IMockInitializer`s, each of them responsible for setting up certain members of the mock object. Currently, 2 initializers are provided (although the client is free to define his/her own initializers):

#### SealedPropertyInitializer

This initializer will inspect a mock's members and check for any properties that cannot be setup by Moq, i.e., any sealed/non-overridable properties.

Each of these properties will be setup in the following manner:

mock.Object.Member = fixture.Create();

#### VirtualMethodInitializer

This initializer will inspect a mock's members and check for any methods that can be setup by Moq, i.e., any virtual/abstract/non-sealed methods.

Each of these methods will be set up in a manner similar to this:

```csharp
//setting up "public int Method(string p1)"
mock.Setup(m => m.Method(It.IsAny()))
.Returns(() => {
var result = fixture.Create(); //retrieve value from the fixture (lazily)
mock.Setup(m => m.Method(It.IsAny()))
.Returns(result); //reuse this value the next time the member is invoked
return result;
});
```

If the method being set up contains any "out" parameters, then the setup becomes:

```csharp
//setting up "public int Method(string p1, out bool p2)"
//value for the "out" parameter must be retrieved eagerly
var outParameter = fixture.Create();
mock.Setup(m => m.Method(It.IsAny(), out outParameter))
.Returns(() => {
var result = fixture.Create();
mock.Setup(m => m.Method(It.IsAny(), out outParameter)))
.Returns(result);
return result;
});
```

In order for a method to be eligible for setup, it needs to:
* be overridable (self-explanatory);
* not have ref parameters;
* due to a limitation in Moq (see the third example in the [Quickstart][2]), a setup for a method with a "ref" parameter will only be matched if the variable used to setup the method is the same as the one used to call the method. Since the setup and the invocation take place in completely different scopes, automatic setup of a method with "ref" parameters is therefore impossible.
* not be generic;
* automatic mocking of generic methods isn't feasible either - we'd have to antecipate any type parameters that this method could be called with. Note that methods that belong to a generic type, but don't introduce any generic type parameters of their own are *not* considered generic themselves and can, therefore, be automatically setup.
* either be non-void *or* have "out" parameters.
* If the method is void and has no "out" parameters then there is nothing worth setting up.

Note that properties and indexers are also implemented as methods (e.g., `get_Age()` and `get_Item(Int32)` respectively). As follows, the `VirtualMethodInitializer` will also set these up.

**Note**: This started out as a separate project entitled `AutoMoq.Boost`, available [here][1]. This project will be marked as "migrated" and discontinued once the pull request is accepted.

[1]: https://github.com/dcastro/AutoMoq.Boost
[2]: https://github.com/Moq/moq4/wiki/Quickstart
`AutoMoqBoostCustomization` is a customization that builds on top of AutoMoq's `AutoMoqCustomization`.

`AutoMoqBoostCustomization` uses the existing `MockPostprocessor` to allows mocks to be retrieved from a fixture, and adds its own `MockSetup` to automatically setup mocks created by the post-processor before returning them to the client.

The mock's members (methods/properties/indexers) will be set up in such a way that return values will be retrieved from a fixture (see examples below). Also, if a method contains any "out" parameters, the value for the outcome of these parameters will also be fetched from a fixture.

`MockSetup` is composed by a collection of `IMockInitializer`s, each of them responsible for setting up certain members of the mock object. Currently, 2 initializers are provided (although the client is free to define his/her own initializers):

#### SealedPropertyInitializer

This initializer will inspect a mock's members and check for any properties that cannot be setup by Moq, i.e., any sealed/non-overridable properties.

Each of these properties will be setup in the following manner:

mock.Object.Member = fixture.Create();

#### VirtualMethodInitializer

This initializer will inspect a mock's members and check for any methods that can be setup by Moq, i.e., any virtual/abstract/non-sealed methods.

Each of these methods will be set up in a manner similar to this:

```csharp
//setting up "public int Method(string p1)"
mock.Setup(m => m.Method(It.IsAny()))
.Returns(() => {
var result = fixture.Create(); //retrieve value from the fixture (lazily)
mock.Setup(m => m.Method(It.IsAny()))
.Returns(result); //reuse this value the next time the member is invoked
return result;
});
```

If the method being set up contains any "out" parameters, then the setup becomes:

```csharp
//setting up "public int Method(string p1, out bool p2)"
//value for the "out" parameter must be retrieved eagerly
var outParameter = fixture.Create();
mock.Setup(m => m.Method(It.IsAny(), out outParameter))
.Returns(() => {
var result = fixture.Create();
mock.Setup(m => m.Method(It.IsAny(), out outParameter)))
.Returns(result);
return result;
});
```

In order for a method to be eligible for setup, it needs to:
* be overridable (self-explanatory);
* not have ref parameters;
* due to a limitation in Moq (see the third example in the [Quickstart][2]), a setup for a method with a "ref" parameter will only be matched if the variable used to setup the method is the same as the one used to call the method. Since the setup and the invocation take place in completely different scopes, automatic setup of a method with "ref" parameters is therefore impossible.
* not be generic;
* automatic mocking of generic methods isn't feasible either - we'd have to antecipate any type parameters that this method could be called with. Note that methods that belong to a generic type, but don't introduce any generic type parameters of their own are *not* considered generic themselves and can, therefore, be automatically setup.
* either be non-void *or* have "out" parameters.
* If the method is void and has no "out" parameters then there is nothing worth setting up.

Note that properties and indexers are also implemented as methods (e.g., `get_Age()` and `get_Item(Int32)` respectively). As follows, the `VirtualMethodInitializer` will also set these up.

**Note**: This started out as a separate project entitled `AutoMoq.Boost`, available [here][1]. This project will be marked as "migrated" and discontinued once the pull request is accepted.

[1]: https://github.com/dcastro/AutoMoq.Boost
[2]: https://github.com/Moq/moq4/wiki/Quickstart