CopyAndUpdateAssertion - I/O 不匹配
CopyAndUpdateAssertion - I/O mismatch
此问题与 AutoFixture 的 CopyAndUpdateAssertion 的使用有关,可在其习语 nuget 中找到。
假设有一个 class 类似于这个:
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());
}
}
是否可以使用 CopyAndUpdateAssertion 测试 Append 方法,假设输入是单值的(例如 'value')并且输出上的 属性 是多值的(例如'Bars1' 属性)?如果是,应该更换哪些默认管道,您能否提供任何关于我应该从哪里开始寻找的指示?
这不是 CopyAndUpdateAssertion
可以解决的问题,我也不知道可以对其进行调整以测试类似的东西。
您可以想出各种方法变体,例如上面的 Append
方法:插入之前而不是之后。附加到字符串,而不是替换它。添加到现有号码。等等
这有点超出了 复制和更新 的概念;它是 复制和更新 然后是更多东西。
显然,如果您经常需要上述 Append
方法之类的方法,它们显然会增加价值,但除此之外,您还可以考虑使用更具组合性的方法。
首先,为了更容易地追加到序列,您可以考虑这样的扩展方法:
public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T value)
{
return source.Concat(new[] { value });
}
如果您想象 Foo
已经有一个 'standard' WithBars1
copy 和 update 方法,您可以获得与以下相同的结果:
var foo1 = foo.WithBars1(foo.Bars1.Append(someBar).ToArray());
诚然,这行代码比 foo1 = foo.Append(someBar)
更复杂或更详细,但另一方面,它需要的测试范围要小得多,因为它是从 'standard' 构建块构建的。
最终,在两三个代码库中做了类似的事情之后,这是让我转向 F# 的众多原因之一,其中大部分已经内置:
let foo' = { foo with Bars1 = foo.Bars1 |> Array.append [| someBar |] }
完全不需要单元测试来支持上述表达式,因为它专门使用 F# 语言特性和内置函数。
此问题与 AutoFixture 的 CopyAndUpdateAssertion 的使用有关,可在其习语 nuget 中找到。
假设有一个 class 类似于这个:
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());
}
}
是否可以使用 CopyAndUpdateAssertion 测试 Append 方法,假设输入是单值的(例如 'value')并且输出上的 属性 是多值的(例如'Bars1' 属性)?如果是,应该更换哪些默认管道,您能否提供任何关于我应该从哪里开始寻找的指示?
这不是 CopyAndUpdateAssertion
可以解决的问题,我也不知道可以对其进行调整以测试类似的东西。
您可以想出各种方法变体,例如上面的 Append
方法:插入之前而不是之后。附加到字符串,而不是替换它。添加到现有号码。等等
这有点超出了 复制和更新 的概念;它是 复制和更新 然后是更多东西。
显然,如果您经常需要上述 Append
方法之类的方法,它们显然会增加价值,但除此之外,您还可以考虑使用更具组合性的方法。
首先,为了更容易地追加到序列,您可以考虑这样的扩展方法:
public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T value)
{
return source.Concat(new[] { value });
}
如果您想象 Foo
已经有一个 'standard' WithBars1
copy 和 update 方法,您可以获得与以下相同的结果:
var foo1 = foo.WithBars1(foo.Bars1.Append(someBar).ToArray());
诚然,这行代码比 foo1 = foo.Append(someBar)
更复杂或更详细,但另一方面,它需要的测试范围要小得多,因为它是从 'standard' 构建块构建的。
最终,在两三个代码库中做了类似的事情之后,这是让我转向 F# 的众多原因之一,其中大部分已经内置:
let foo' = { foo with Bars1 = foo.Bars1 |> Array.append [| someBar |] }
完全不需要单元测试来支持上述表达式,因为它专门使用 F# 语言特性和内置函数。