如何在C#/ VS中构建自定义断言?

时间:2009-05-30 23:33:17

标签: c# visual-studio unit-testing

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

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

我希望有一个断言方法,如:

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

最好的方法是什么?

7 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

如果您能够使用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个词典长度的检查 即如果长度不同,您可以使用 ,但

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

答案 4 :(得分:0)

@Sprintstar在评论@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 :(得分:0)

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

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

Assert.That.AreEquivalent(propsExpected,propsActual);

答案 6 :(得分:-3)

这里的诀窍是使用名为extension methods

的.Net 3.5的新功能

例如,要使用上面提供的代码使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);