我正在编写一个单元测试,以针对对象集合的属性进行断言。属性之一是整数,对于集合中的每个对象,该整数应增加一。但是,如果您理解我的意思,则不能保证将项目添加到集合中的顺序与它们被“排序”的顺序相同。
我希望能够写一个断言语句来达到以下效果:
return FirebaseAnimatedList(
query: FirebaseDatabase.instance.reference().child('users/' + user.uid),
itemBuilder: (context, snapshot, animation, index) {
return Row(children: <Widget>[
Text(
snapshot.value['source'],
style: TextStyle(fontSize: 13.0),
),
]);
});
答案 0 :(得分:4)
好吧,我们可以创建一个LINQ
表达式,该表达式应该只返回1
的序列。您应该能够基于此构建断言:
var ordered = lotsOfThings.OrderBy(t=>t.SequenceNumber);
var final = ordered.Zip(ordered.Skip(1),(f,s)=>s-f);
(不确定确切使用的框架,但是大多数框架应该具有Assert
关于枚举/集合的某些功能。例如,对于MSTest,您将使用CollectionAssert
类中的某些东西)< / p>
(取决于您,如果您认为值得在.ToList()
定义上添加ordered
来对此进行优化。我通常不会对测试进行微优化,并且我认为我们不会处理数百万个我还假设您不想修改原始列表,因为您可以在此处Sort()
,而不用引入LINQ OrderBy
)
答案 1 :(得分:2)
只需遍历列表并在循环内添加Assert。
var orderedList = list.OrderBy(a=>a.SequenceNumber);
var i = orderedList.First().SequenceNumber;
foreach(var item in orderedList)
{
Assert.AreEqual(item.SequenceNumber, i++);
}
答案 2 :(得分:2)
另一种风味:
[Test]
public void SomethingSequenceNumberTest()
{
var lotsOfThings = new List<Something>
{
new Something { SequenceNumber = 1 },
new Something { SequenceNumber = 2 },
new Something { SequenceNumber = 4 },
new Something { SequenceNumber = 3 },
};
// extract the sequence numbers into a list
var sequenceNumbers = lotsOfThings.Select(x => x.SequenceNumber)
.ToList();
sequenceNumbers.Sort();
// Enumerable.Range will create a new enumerable
// with values ranging from .First() to .Last(),
// i.e. [1, 2, 3, 4]
Assert.IsTrue(Enumerable.Range(sequenceNumbers.First(), sequenceNumbers.Last())
.SequenceEqual(sequenceNumbers));
}
工作原理:
将序列号提取到自己的列表(sequenceNumbers
)中然后进行排序,这将使用Enumerable.Range
生成指定范围内的整数序列(该范围较小)和最大的序列号),然后使用Enumerable.SequenceEqual
将生成的可枚举与sequenceNumbers
进行相等性比较(通过使用默认的相等性比较器为其类型进行比较)。
答案 3 :(得分:2)
没有循环,只有两行。
var expected = Enumerable.Range(1, lotsOfThings.Count()).Select(i => i).ToArray();
CollectionAssert.AreEquivalent(expected, lotsOfThings.Select(t => t.SequenceNumber).ToArray(), string.Join("; ", item));
答案 4 :(得分:1)
我们可以遍历整个集合,然后回顾一下以前的值是否小一个:
var incremental = true;
lotsOfThings = lotsOfThings.OrderBy(l => l.SequenceNumber).ToList();
for (var i = 0; i < lotsOfThings.Count; i++)
{
if (i == 0)
continue;
var previous = lotsOfThings[i - 1].SequenceNumber;
var current = lotsOfThings[i].SequenceNumber;
// Great! The current one is 1 higher then the previous one, continue!
if (previous == current - 1)
continue;
// Done checking, this list is not incrementing properly
incremental = false;
break;
}
Assert.IsTrue(incremental);
答案 5 :(得分:1)
只需使用循环:
[Test]
public void SomethingSequenceNumberTest()
{
var lotsOfThings = new List<Something>
{
new Something { SequenceNumber = 1 },
new Something { SequenceNumber = 2 },
new Something { SequenceNumber = 4 },
new Something { SequenceNumber = 3 },
};
// Assert that a sequence of integer are incremental, that there are no repetitions or gaps.
var index = lotsOfThings.First().SequenceNumber;
lotsOfThings
.OrderBy(t => t.SequenceNumber)
.ToList()
.ForEach(t =>
{
Assert.That(t.SequenceNumber, Is.EqualTo(index));
index++;
});
}
答案 6 :(得分:1)
我已经提供了自己的断言方法实现。如果您需要在多个测试中进行这样的断言,这可能会有所帮助。
public void AssertIsSequenced<T>(IEnumerable<T> list, Func<T, int> valueExtractor)
{
int? lastExtractedValue = null;
foreach (T item in list)
{
int extractedValue = valueExtractor(item);
if (lastExtractedValue != null && extractedValue != lastExtractedValue + 1)
{
Assert.Fail($"{extractedValue} after {lastExtractedValue} does not follow the sequence rule.");
}
lastExtractedValue = extractedValue;
}
}
[TestMethod]
public void SomethingSequenceNumberTest()
{
var lotsOfThings = new List<Something>
{
new Something { SequenceNumber = 1 },
new Something { SequenceNumber = 2 },
new Something { SequenceNumber = 4 },
new Something { SequenceNumber = 3 },
};
// Assert that a sequence of integer are incremental, that there are no repetitions or gaps.
AssertIsSequenced(lotsOfThings.OrderBy(something => something.SequenceNumber), something => something.SequenceNumber);
}