繁体   English   中英

C#单元测试中的双向列表比较

[英]two-way list comparison in C# unit test

在我的C#单元测试中,我经常根据ID列表查询行列表。 然后,我想确保1)对于所有ID,至少有一行找到具有该ID且2)对于所有返回的行,每行具有要在其中找到的ID列表中的ID。 以下是我通常如何确保:

Assert.IsTrue(ids.All(
    id => results.Any(result => result[primaryKey].Equals(id))
), "Not all IDs were found in returned results");

Assert.IsTrue(results.All(
    result => ids.Any(id => result[primaryKey].Equals(id))
), "Returned results had unexpected IDs");

我认为AnyAll的使用对于这样的检查很方便,但是我想看看是否有人认为这比可能的更不易读,或者是否有更好的方法来进行这样的双向检查。 我在Visual Studio 2008 Team System中使用MSTest进行单元测试。 这可能应该是社区维基,如果它太主观。

编辑:我现在正在使用基于Aviad P.建议的解决方案,以及以下测试通过的事实:

string[] ids1 = { "a", "b", "c" };
string[] ids2 = { "b", "c", "d", "e" };
string[] ids3 = { "c", "a", "b" };
Assert.AreEqual(
    1,
    ids1.Except(ids2).Count()
);
Assert.AreEqual(
    2,
    ids2.Except(ids1).Count()
);
Assert.AreEqual(
    0,
    ids1.Except(ids3).Count()
);

您可以选择使用Except运算符:

var resultIds = results.Select(x => x[primaryKey]);

Assert.IsTrue(resultIds.Except(ids).Count() == 0,
 "Returned results had unexpected IDs");

Assert.IsTrue(ids.Except(resultIds).Count() == 0,
 "Not all IDs were found in returned results");

IMO,尽管不是那么可读。 创建并记录返回true / false的方法。 然后调用Assert.IsTrue(methodWithDescriptiveNameWhichReturnsTrueOrfalse(),“失败的原因”);

下面是我处理两个枚举的代码片段,并在进行单元测试时抛出异常在MS Test中,它可能会有所帮助:

使用

比较两个枚举:

 MyAssert.AreEnumerableSame(expected,actual);

管理例外

MyAssert.Throws<KeyNotFoundException>(() => repository.GetById(1), string.Empty);

public class MyAssert
    {
        public class AssertAnswer
        {
            public bool Success { get; set; }
            public string Message { get; set; }
        }

        public static void Throws<T>(Action action, string expectedMessage) where T : Exception
        {
            AssertAnswer answer = AssertAction<T>(action, expectedMessage);

            Assert.IsTrue(answer.Success);
            Assert.AreEqual(expectedMessage, answer.Message);
        }

        public static void AreEnumerableSame(IEnumerable<object> enumerable1, IEnumerable<object> enumerable2)
        {
            bool isSameEnumerable = true;
            bool isSameObject ;

            if (enumerable1.Count() == enumerable2.Count())
            {
                foreach (object o1 in enumerable1)
                {
                    isSameObject = false;
                    foreach (object o2 in enumerable2)
                    {
                        if (o2.Equals(o1))
                        {
                            isSameObject = true;
                            break;
                        }
                    }
                    if (!isSameObject)
                    {
                        isSameEnumerable = false;
                        break;
                    }
                }
            }
            else
                isSameEnumerable = false;

            Assert.IsTrue(isSameEnumerable);
        }

        public static AssertAnswer AssertAction<T>(Action action, string expectedMessage) where T : Exception
        {
            AssertAnswer answer = new AssertAnswer();

            try
            {
                action.Invoke();

                answer.Success = false;
                answer.Message = string.Format("Exception of type {0} should be thrown.", typeof(T));
            }
            catch (T exc)
            {
                answer.Success = true;
                answer.Message = expectedMessage;
            }
            catch (Exception e)
            {
                answer.Success = false;
                answer.Message = string.Format("A different Exception was thrown {0}.", e.GetType());
            }

            return answer;
        }
    }

NUnit具有CollectionAssert系列断言,有助于提高可读性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM