CopyAndUpdateAssertion - I / O mismatch

This question pertains to the use of AutoFixture's CopyAndUpdateAssertion found in his Idiom issue.

Suppose someone has a class like this:

public class Foo
{
    public static readonly Foo Empty = new Foo(
        new Bar1[0], 
        new Bar2[0]);

    private readonly Bar1[] _bars1;
    private readonly Bar2[] _bars2;

    public Foo(
        Bar1[] bars1,
        Bar2[] bars2)
    {
        if (bars1 == null) 
          throw new ArgumentNullException("bars1");
        if (bars2 == null) 
          throw new ArgumentNullException("bars2");

        _bars1 = bars1;
        _bars2 = bars2;
    }

    public Bar1[] Bars1
    {
        get { return _bars1; }
    }

    public Bar2[] Bars2
    {
        get { return _bars2; }
    }

    public Foo Append(Bar1 value)
    {
        if (value == null) throw new ArgumentNullException("value");
        return new Foo(
            _bars1.Concat(new[] {value}).ToArray(),
            _bars2);
    }

    public Foo Append(Bar2 value)
    {
        if (value == null) throw new ArgumentNullException("value");
        return new Foo(
            _bars1,
            _bars2.Concat(new[] { value }).ToArray());
    }

    public bool Equals(Foo other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return _bars1.SequenceEqual(other._bars1) &&
               _bars2.SequenceEqual(other._bars2);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != GetType()) return false;
        return Equals((Foo)obj);
    }

    public override int GetHashCode()
    {
        return _bars1.Aggregate(0, (current, next) => current ^ next.GetHashCode()) ^
               _bars2.Aggregate(0, (current, next) => current ^ next.GetHashCode());
    }
}

      

Is it possible to test Append methods with CopyAndUpdateAssertion, given that the input is unambiguous (for example, "value") and the property in the output is multivalued (for example, the property "Bars1")? If so, what parts of the standard plumbing should be replaced and can you provide any guidance as to where should I start looking?

+3


source to share


1 answer


This is not something that can address CopyAndUpdateAssertion

and I don't know that it can be configured to test something like this.

You can come up with all sorts of variations of methods such as the methods Append

above: Insert before, not after. Append to string instead of replacing it. Add to existing number. Etc.

This is somewhat different from the concept of copy and update; it copies and updates and then something else.

Obviously, if you want methods like the above methods Append

, they will obviously add value, but otherwise you might want to consider a more complex approach as well.

First, to make it easier to add to sequences, you might consider extending as follows:

public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T value)
{
    return source.Concat(new[] { value });
}

      

If you assume you Foo

already have a "standard" WithBars1

copy and update method, you can achieve the same result as:



var foo1 = foo.WithBars1(foo.Bars1.Append(someBar).ToArray());

      

Of course, this line of code is more complex or more detailed than foo1 = foo.Append(someBar)

that, but on the other hand it requires much less testing coverage as it is built from building blocks.


Ultimately, however, after doing something like this in two or three codebases, it was one of the many reasons that led me to switch to F #, where most of this is already built in:

let foo' = { foo with Bars1 = foo.Bars1 |> Array.append [| someBar |] }

      

No unit tests are required to support the above expression, as it exclusively uses F # language features and built-in functions.

+3


source







All Articles