2

Closed

Conventions for arrays and other multiples

description

AutoFixture has no inherent understanding of arrays or other multiples like IEnumerable<T>. Consider implementing a set of ISpecimenBuilders that relays requests for arrays etcs. to requests for many instances of the given type. It might be most appropriate to define this as an optional set that can be explicitly added to a Fixture.
Closed Feb 3, 2011 at 9:25 PM by ploeh
Implemented with changeset 8d0bda5575db apart from the part about filling read-only ICollections, which is deferred until an indeterminate time in the future.

comments

ploeh wrote Jul 29, 2010 at 3:26 PM

Implemented for arrays in changeset 537784347a77.

ploeh wrote Jul 30, 2010 at 7:44 PM

Right now my thinking on this issue is as follows:

Array support is implemented and will be an integral part of AutoFixture 2.0. This makes sense since arrays are first-class citizens in .NET and AutoFixture always had rather lacking support of arrays: it would create an array, but not fill it - a situation that was neither here nor there. In AutoFixture 2.0, requests for arrays will be automatically fulfilled with a populated array of the requested type. This feature is already in the source code repository.

However, the rest of this issue will be deferred to after AutoFixture 2.0. This is because it has the potential to change how AutoFixture behaves. In general, support for multiples fall in two categories: 1) abstractions 2) concrete types. Let's look at each in turn:

1) Abstractions:
These would be covered by requests for IEnumerable<T>, ICollection<T>, IList<T> as well as any custom interfaces or abstract base classes derived from those, but defined by the user. As far as AutoFixture is concerned, these are interfaces just like any other interface, and will not be resolved unless explicitly addressed by a customization, or generally be an auto-mocking extension. While AutoFixture could have special-case handling for the BCL interfaces, it can't have that for custom derivatives. Furthermore, if an auto-mocking extension is in play, which one should handle a request for IEnumerable<T>? The auto-mocking extension or the multiple-convention? As this case is at best ambiguous, my take on this at the moment is that this should be an optional feature that can be explicitly added to a Fixture instance if desired.

2) Concrete types
This covers requests for List<T>, Collection<T> and so on, as well as derived classes defined by the user. These tend to have proper public constructors and will typically be created and instantiated by AutoFixture. However, since most of these constructors initialize empty lists, the created instances tend to be empty. Once again, redefining this behavior is a breaking change and would require special-casing, so is better left as an optional feature.

In short, I think this feature is very valuable, but it will have to be an optional feature that can be explicitly added to a Fixture instance.

ploeh wrote Oct 11, 2010 at 2:57 PM

Another idea: Let's say we have a type like this:

public class Foo
{
public ICollection<Bar> Bars { get; }
}

In some cases we might be interested in a convention that adds 'many' Bar instances to Bars, even though it's read-only. This is essentially just a convention around the AddManyTo method.

Such an optional convention could simply apply to all read-only properties that expose ICollection<T> (or a derived interface).

ploeh wrote Jan 13, 2011 at 9:16 PM

So far I have identified the following types that this feature should support:
  • IEnumerable<T>
  • ICollection<T>
  • IList<T>
  • IDictionary<TKey, TValue>
  • Arrays
  • Collection<T>
  • List<T>
  • Dictionary<T>
  • HashSet<T>