c#断言整数序列是增量的

时间:2018-07-25 09:00:11

标签: c# unit-testing

我正在编写一个单元测试,以针对对象集合的属性进行断言。属性之一是整数,对于集合中的每个对象,该整数应增加一。但是,如果您理解我的意思,则不能保证将项目添加到集合中的顺序与它们被“排序”的顺序相同。

我希望能够写一个断言语句来达到以下效果:

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),
        ),
      ]);
    });

7 个答案:

答案 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);
    }