gpt4 book ai didi

c# - NUnit CollectionAssert.AreEqual(expected,actual) vs Assert.IsTrue(expected.SequenceEqual(actual))

转载 作者:太空狗 更新时间:2023-10-30 01:35:17 32 4
gpt4 key购买 nike

我有一些对象被放入队列中。队列中的所有对象都实现相同的基接口(interface),这也要求它们实现 IEquatable<>。

我想验证是否以正确的顺序将正确的对象放入队列中。

当我编写一个断言 CollectionAssert.AreEqual(expected,actual) 的测试时,测试失败,说明虽然队列是预期长度,但它在索引 0 处不同。

但是,当我将测试断言写为 Assert.IsTrue(expected.SequenceEqual(actual)) 时,测试通过了。

在我看来,这两个断言应该是相同的,但显然它们是完全不同的。

NUnit 的网站对集合断言方法的介绍不是很详细,而 Linq 文档虽然更详细,但如果无法与 NUnit 使用集合断言方法进行比较,也无济于事。

这两个断言有何不同?

编辑 - 添加细节

这是被测代码以及我希望得到相同结果的两个测试。

public enum ArgumentTypeEnum
{
SpiceworksDbName,
DestinationDbName,
DestinationServerName
}

public interface IArgument : IEquatable<IArgument>
{
}

public interface ICommandArgument : IArgument
{
ArgumentTypeEnum ArgumentType { get; }
}

internal interface IValueArgument : IArgument
{
String ArgumentValue { get; }
}

public class CommandArgument : ICommandArgument
{
public CommandArgument(ArgumentTypeEnum argumentType) {
ArgumentType = argumentType;
}

public ArgumentTypeEnum ArgumentType { get; private set; }

public bool Equals(IArgument other)
{
if (other == null)
{
return false;
}

var otherAsCommandArg = other as CommandArgument;
if (otherAsCommandArg == null)
{
return false;
}

return ArgumentType == otherAsCommandArg.ArgumentType;
}
}

public class ValueArgument : IValueArgument
{
public ValueArgument(String argumentValue)
{
ArgumentValue = argumentValue;
}

public string ArgumentValue { get; private set; }

public bool Equals(IArgument other)
{
if (other == null)
{
return false;
}

var otherAsValueArg = other as ValueArgument;
if (otherAsValueArg == null)
{
return false;
}

return ArgumentValue == otherAsValueArg.ArgumentValue;
}
}

public class Tokenizer
{
public Queue<IArgument> TokenizeArguments(string[] args) {
var tokenQueue = new Queue<IArgument>();
args.ToList().ForEach((arg) => {
if (arg.StartsWith("-"))
{
switch (arg)
{
case "-sd":
tokenQueue.Enqueue(new CommandArgument(ArgumentTypeEnum.SpiceworksDbName));
break;
case "-dd":
tokenQueue.Enqueue(new CommandArgument(ArgumentTypeEnum.DestinationDbName));
break;
case "-ds":
tokenQueue.Enqueue(new CommandArgument(ArgumentTypeEnum.DestinationServerName));
break;
default:
tokenQueue.Enqueue(new ValueArgument(arg));
break;
}
}
else
{
tokenQueue.Enqueue(new ValueArgument(arg));
}
});
return tokenQueue;
}
}

[TestFixture]
public class TokenizerSpecs
{
///Passes
[Test]
public void Tokenizer_MultipleCommandsAndValues_TokenizesAsExpected1() {
var args = new[]
{
"-sd", @"\\some\Directory\foo.db", "-dd", "some database name", "-ds", "Server.name", "somerandomarg",
"-unreconized"
};
var t = new Tokenizer();
var actualResult = t.TokenizeArguments(args);

var expectedResult = new Queue<IArgument>();
expectedResult.Enqueue(new CommandArgument(ArgumentTypeEnum.SpiceworksDbName));
expectedResult.Enqueue(new ValueArgument(@"\\some\Directory\foo.db"));
expectedResult.Enqueue(new CommandArgument(ArgumentTypeEnum.DestinationDbName));
expectedResult.Enqueue(new ValueArgument("some database name"));
expectedResult.Enqueue(new CommandArgument(ArgumentTypeEnum.DestinationServerName));
expectedResult.Enqueue(new ValueArgument("Server.name"));
expectedResult.Enqueue(new ValueArgument("somerandomarg"));
expectedResult.Enqueue(new ValueArgument("-unreconized"));

Assert.IsTrue(expectedResult.SequenceEqual(actualResult));
}

///Fails
[Test]
public void Tokenizer_MultipleCommandsAndValues_TokenizesAsExpected2()
{
var args = new[]
{
"-sd", @"\\some\Directory\foo.db", "-dd", "some database name", "-ds", "Server.name", "somerandomarg",
"-unreconized"
};
var t = new Tokenizer();
var actualResult = t.TokenizeArguments(args);

var expectedResult = new Queue<IArgument>();
expectedResult.Enqueue(new CommandArgument(ArgumentTypeEnum.SpiceworksDbName));
expectedResult.Enqueue(new ValueArgument(@"\\some\Directory\foo.db"));
expectedResult.Enqueue(new CommandArgument(ArgumentTypeEnum.DestinationDbName));
expectedResult.Enqueue(new ValueArgument("some database name"));
expectedResult.Enqueue(new CommandArgument(ArgumentTypeEnum.DestinationServerName));
expectedResult.Enqueue(new ValueArgument("Server.name"));
expectedResult.Enqueue(new ValueArgument("somerandomarg"));
expectedResult.Enqueue(new ValueArgument("-unreconized"));

CollectionAssert.AreEqual(expectedResult, actualResult);
}
}

最佳答案

我已经查看了 NUnit 的源代码,看来您这里有一个错误。比较由 NUnitEqualityComparer.EnumerablesEqual 完成,随后通过 NUnitEqualityComparer.ObjectsEqual 比较每个元素。我们可以使用这个对象做简单的测试:

var n = new NUnitEqualityComparer();
var tolerance = Tolerance.Zero;
var equal = n.AreEqual(new CommandArgument(ArgumentTypeEnum.SpiceworksDbName),
new CommandArgument(ArgumentTypeEnum.SpiceworksDbName),
ref tolerance);

这个测试返回false!

不知何故,ObjectsEqual 并没有在对象的 Equals 方法中结束。需要对源代码进行调试才能找出原因,但这个测试足以证明存在错误。

关于c# - NUnit CollectionAssert.AreEqual(expected,actual) vs Assert.IsTrue(expected.SequenceEqual(actual)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26390953/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com