[英]Assert.That() does not evaluate given constraint
我有一個字符串值列表。 我用 foreach 迭代這個列表。 我申請了每個列表項 Assert.That() 方法。 現在來個轉折:我給出了一個返回 IResolveConstraint 的函數作為該方法的第二個參數。 當函數返回Has.Exactly(1).Contains() ,然后在列表的第二項( foreach 的第二次迭代)處,斷言評估(拋出)此消息:“預期:包含“值”的集合”。 但是斷言應該通過,因為它正在驗證一個項目,而不是一個集合。
我有 NUnit 3.2.1。 我升級到 3.12.0 版,之后消息從:“預期:包含“值”的集合”更改為消息:“預期:某些項目等於“值””並且斷言仍然沒有通過。
public class Verifiers
{
public void VerifyCollectedValues(List<string> collectedValues, List<string> expectedValues
, string collectedValuesFrom, int countOfValueExpactance, bool verifyExactSameValue = true)
{
// Create a constraint function
Func<string, IResolveConstraint> constraintFunction = CreateConstraintFunction(Has.Exactly(countOfValueExpactance), verifyExactSameValue);
// Pass the constraint to the method
VerifyCollectedValues(constraintFunction, collectedValues, expectedValues, collectedValuesFrom);
}
public void VerifyCollectedValues(Func<string, IResolveConstraint> constraintFunction, List<string> collectedValues, List<string> expectedValues
, string collectedValuesFrom)
{
foreach (string expectedValue in expectedValues)
{
// Apply the constraint
Assert.That(collectedValues, constraintFunction(expectedValue));
}
}
public Func<string, IResolveConstraint> CreateConstraintFunction(ConstraintExpression constraintExpression, bool verifyExactSameValue)
{
if (verifyExactSameValue)
{
return (string value) => constraintExpression.EqualTo(value);
}
else
{
return (string value) => constraintExpression.Contains(value);
}
}
}
示例代碼:
Verifiers verifiers = new Verifiers();
List<string> expectedValues = new List<string>()
{
"value1",
"value2",
"value3",
};
var collectedValues = new List<string>()
{
"some_value0",
"some_value1",
"some_value2",
"some_value3",
};
// This passes
foreach(string expectedValue in expectedValues)
{
Assert.That(collectedValues, Has.Exactly(1).Contains(expectedValue));
}
// This fails with the message: "Expected: collection containing "value2"" (with NUnit v3.2.1) / "Expected: some item equal to "value2""(with NUnit v3.12.0)
verifiers.VerifyCollectedValues(collectedValues, expectedValues, 1, false);
我的假設是 IResolveConstraint 導致了這個問題。 我不明白的是為什么列表的第一項通過但第二項沒有通過。
我將不勝感激任何答案。
更新:
我已經做了一些編輯,並在此基礎上排除了 IResolveConstraint 導致問題的可能性。 這是當前代碼的示例:
public class Verifiers
{
public void VerifyCollectedValues(List<string> collectedValues, List<string> expectedValues, string collectedValuesFrom, int countOfValueExpectance, bool verifyExactSameValue = true)
{
VerifyCollectedValues(CreateConstraintExpressionExactly(countOfValueExpectance), collectedValues, expectedValues, collectedValuesFrom, verifyExactSameValue);
}
private void VerifyCollectedValues(ConstraintExpression constraintExpression, List<string> collectedValues, List<string> expectedValues, string collectedValuesFrom, bool exactSameValue)
{
if (exactSameValue)
{
VerifyCollectedValuesEqualTo(constraintExpression, collectedValues, expectedValues, collectedValuesFrom);
}
else
{
VerifyCollectedValuesContains(constraintExpression, collectedValues, expectedValues, collectedValuesFrom);
}
}
private void VerifyCollectedValuesEqualTo(ConstraintExpression constraintExpression, List<string> collectedValues, List<string> expectedValues, string collectedValuesFrom)
{
Func<string, EqualConstraint> constraintFunction = (string value) => constraintExpression.EqualTo(value);
foreach (string expectedValue in expectedValues)
{
Assert.That(collectedValues, constraintFunction(expectedValue));
}
}
private void VerifyCollectedValuesContains(ConstraintExpression constraintExpression, List<string> collectedValues, List<string> expectedValues, string collectedValuesFrom)
{
// if I don't use constraintExpression but write the expression manually (Has.Exactly(1).Contains(value)), then it works just fine
Func<string, ContainsConstraint> constraintFunction = (string value) => constraintExpression.Contains(value);
foreach (string expectedValue in expectedValues)
{
Assert.That(collectedValues, constraintFunction(expectedValue));
}
}
private ConstraintExpression CreateConstraintExpressionExactly(int countOfExpectance)
{
return Has.Exactly(countOfExpectance);
}
var verifiers = new Verifiers();
List<string> expectedValues = new List<string>()
{
"value1",
"value2",
"value3",
};
var collectedValues = new List<string>()
{
"some_value0",
"some_value1",
"some_value2",
"some_value3",
};
// This one pass successfully
foreach(string expectedValue in expectedValues)
{
Assert.That(collectedValues, Has.Exactly(1).Contains(expectedValue));
}
// But this one still doesn't pass and fails at the second list item "value2"
verifiers.VerifyCollectedValues(collectedValues, expectedValues, "list of strings", 1, false);
如果實際值為非集合,您認為Has.Exactly(1).EqualTo()
將通過的假設是不正確的。 如果傳遞非集合類型, ExactCountConstraint
將出錯(與失敗不完全相同)。
但是,在這種情況下, string
是字符的集合,因此它會嘗試運行。
問題是您正在使用集合約束,它迭代列表,但您自己也在迭代它。 你要么自己做這一切(這看起來很傻),要么依靠ExactCountConstraint to do the work
。
如果您繼續自己迭代列表,則不應使用任何集合約束。 在示例情況下,您只需使用Is.EqualTo()
。
好吧,錯誤實際上在您的實現中,因為您一直在傳遞 ConstraintExpression。 如果您嘗試分解工作代碼並為每個驗證創建方法,您將得到如下內容:
[Test]
public void ListCompareTest()
{
List<string> expectedValues = new List<string>()
{
"value1",
"value2",
"value3",
};
var collectedValues = new List<string>()
{
"some_value0",
"some_value1",
"some_value2",
"some_value3",
};
int count = 1;
// This one pass successfully
foreach (string expectedValue in expectedValues)
{
ItemsConstraintExpression itemsConstraintExpression = GetExactly(count);
// this code works
Assert.That(collectedValues, GetContains(expectedValue, itemsConstraintExpression));
}
// this code works as well
DoVerification(expectedValues, collectedValues, 1, false);
}
public static void DoVerification(List<string> expectedList, List<string> actualList, int exactlyCount, bool equalsOrContains)
{
if (equalsOrContains)
{
foreach (var expectedValue in expectedList)
{
Assert.That(actualList, GetEquals(expectedValue, GetExactly(exactlyCount)));
}
}
else
{
foreach (var expectedValue in expectedList)
{
Assert.That(actualList, GetContains(expectedValue, GetExactly(exactlyCount)));
}
}
}
private static EqualConstraint GetEquals(string expectedValue, ItemsConstraintExpression itemsConstraintExpression)
{
return itemsConstraintExpression.EqualTo(expectedValue);
}
private static ContainsConstraint GetContains(string expectedValue, ItemsConstraintExpression itemsConstraintExpression)
{
return itemsConstraintExpression.Contains(expectedValue);
}
private static ItemsConstraintExpression GetExactly(int count)
{
return Has.Exactly(count);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.