在我的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");
我认为使用Any
和All
对于此类检查很方便,但我想知道是否有人认为这样可读性低于可能性,或者是否有更好的方式做这样的双向检查。我在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()
);
答案 0 :(得分:4)
您可以选择使用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");
答案 1 :(得分:3)
IMO,尽管不那么可读。创建并记录返回true / false的方法。然后调用Assert.IsTrue(methodWithDescriptiveNameWhichReturnsTrueOrfalse(),“失败的原因”);
答案 2 :(得分:1)
下面是我处理两个枚举的代码片段,并在进行单元测试时抛出异常在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;
}
}
答案 3 :(得分:0)
NUnit具有CollectionAssert
断言系列,有助于提高可读性。