【问题标题】:How to build custom assertions in C#/VS?如何在 C#/VS 中构建自定义断言?
【发布时间】:2009-05-30 23:33:17
【问题描述】:

我在一些代码中遇到了一个错误,它从一些文本中提取元数据并将其放入字典中。

当我比较两个字典对象时,我的测试失败了,因为键的顺序不同。我真的不在乎钥匙的顺序。

我想要一个可用的断言方法,例如:

Assert.AreEquivalent(propsExpected,propsActual)

评估如下:

Assert.AreEqual(propsExpected.Count, propsActual.Count);
foreach (var key in propsExpected.Keys)
{
    Assert.IsNotNull(props[key]);
    Assert.AreEqual(propsExpected[key], props[key]);
}

最好的方法是什么?

【问题讨论】:

    标签: c# visual-studio unit-testing


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      如果你会使用 LINQ,

      void Main() { Dictionary d1 = new Dictionary<int, string>(); Dictionary d2 = new Dictionary<int, string>(); d1.Add(1, "1"); d1.Add(2, "2"); d1.Add(3, "3"); d2.Add(2, "2"); d2.Add(1, "1"); d2.Add(3, "3"); Console.WriteLine(d1.Keys.Except(d2.Keys).ToArray().Length); }

      这会将 0 打印到控制台。除了尝试在上面的示例中找到两个列表之间的差异。

      你可以把这个和0比较一下,看看有没有区别。

      编辑:在执行此操作之前,您可以添加检查以比较 2 个字典的长度。
      即您可以使用除外,如果长度不同。

      【讨论】:

        【解决方案3】:

        使用 NUnit,您可以使用 Is.EquivalentTo() 约束比较两个集合。此约束将评估集合并检查集合是否具有相同的元素,但它不关心顺序。

        Documentation for CollectionEquivalentConstraint 如果您不使用 NUnit,那么您正在使用的测试框架中可能存在类似的东西?

        【讨论】:

          【解决方案4】:

          正如@Sprintstar 在 cmets 中为@Michael La Voie 的答案指出的那样,由于 Assert 类是静态的,因此无法扩展它,我解决此问题的方法通常是创建一个包含以下内容的测试存储库我的自定义方法具有多个断言和其他验证发生在同一方法中。例如-

          public static class MyTestRepository
          {   
              public static void ArePropsEquivalent(
                  Dictionary<string, int> propsExpected, 
                  Dictionary<string, int> propsActual)
              {
                  //Multiple Asserts and validation logic
                  //required for Equivalence goes here
              }
          
              public static void ArePropsSimilar(
                  Dictionary<string, int> propsExpected, 
                  Dictionary<string, int> propsActual)
              {
                  //Multiple Asserts and validation logic 
                  //required for similarity goes here
              }
          }
          

          然后我从单元测试方法中调用这些方法。

          [TestMethod]
          public void TestMthod1()
          {
              //Props declaration goes here
              MyTestRepository.ArePropsEquivalent(propsExpected, propsActual);
          }
          
          [TestMethod]
          public void TestMthod2()
          {
              //Props declaration goes here
              MyTestRepository.ArePropsSimilar(propsExpected, propsActual);
          }
          

          这样我可以在实际的单元测试用例方法中写得更少,做更多的事情,并保持模块化(在不同模型的情况下)。

          【讨论】:

            【解决方案5】:

            现在有可能(可能是 MS 添加的,因为最初回答了这个问题) - 如果您使用 That 单例,扩展将起作用。

            在这种情况下,扩展可以被称为:

            Assert.That.AreEquivalent(propsExpected,propsActual);
            

            【讨论】:

              【解决方案6】:

              【讨论】:

                【解决方案7】:

                这里的诀窍是使用 .Net 3.5 的一个新功能 extension methods

                例如,要使用上面提供的代码让 Assert 类支持 AreEquivalent 方法,您可以执行以下操作:

                public static class MyAssertExtensions
                {
                    public static void AreEquivalent(this Assert ast, 
                        Dictionary<string, int> propsExpected, 
                        Dictionary<string, int> propsActual)
                    {
                        Assert.AreEqual(propsExpected.Count, propsActual.Count);
                        foreach (var key in propsExpected.Keys)
                        {
                            Assert.IsNotNull(props[key]);
                            Assert.AreEqual(propsExpected[key], props[key]);
                        }
                    }
                }
                

                这样你实际上可以像这样调用断言:

                Assert.AreEquivalent(propsExpected,propsActual);
                

                【讨论】:

                • 这里的问题是,如果两个字典中的元素顺序不同,即使元素相等,断言也会失败
                • @Marwan:不,它只断言集合的大小相同,并且对于集合 1 中的每个键,集合 2 中也存在具有相同值的相同键。订单永远不是问题。
                • 要调用这个你需要'Assert.That.AreEquivalent()'
                • 您不能为 Assert 创建扩展方法,因为它是一个静态类,请参阅:stackoverflow.com/questions/7020503/…
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-09-14
                • 1970-01-01
                • 2014-07-17
                • 1970-01-01
                • 2019-07-09
                • 2011-05-04
                相关资源
                最近更新 更多