gpt4 book ai didi

c# - 单元测试表达式树

转载 作者:可可西里 更新时间:2023-11-01 08:41:49 28 4
gpt4 key购买 nike

我最近需要构建一个表达式树,所以我写了一个像这样的测试方法......

    /// <summary>
///
/// </summary>
[TestMethod()]
[DeploymentItem("WATrust.Shared.Infrastructure.dll")]
public void BuildForeignKeysContainsPredicate_shoud_build_contains_predicate()
{
RemoteEntityRefLoader_Accessor<ReferencedEntity> target = CreateRemoteEntityRefLoader_Accessor();

List<object> foreignKeys = new List<object>() { 1, 2, 3, 4 };
Expression<Func<ReferencedEntity, bool>> expected = (ReferencedEntity referencedEntity) => foreignKeys.Contains(referencedEntity.Id);
Expression<Func<ReferencedEntity, bool>> actual;

actual = target.BuildForeignKeysContainsPredicate(foreignKeys, "Id");

Assert.AreEqual(expected.ToString(), actual.ToString());
}

当我终于让“BuildForeignKeysContainsPredicate”方法工作时,我永远无法让测试通过...这是方法:

    /// <summary>
///
/// </summary>
/// <param name="foreignKeys"></param>
/// <returns></returns>
private Expression<Func<TReferencedEntity, bool>> BuildForeignKeysContainsPredicate(List<object> foreignKeys, string primaryKey)
{
Expression<Func<TReferencedEntity, bool>> result = default(Expression<Func<TReferencedEntity, bool>>);

try
{
ParameterExpression entityParameter = Expression.Parameter(typeof(TReferencedEntity), "referencedEntity");
ConstantExpression foreignKeysParameter = Expression.Constant(foreignKeys, typeof(List<object>));
MemberExpression memberExpression = Expression.Property(entityParameter, primaryKey);
Expression convertExpression = Expression.Convert(memberExpression, typeof(object));
MethodCallExpression containsExpression = Expression.Call(foreignKeysParameter
, "Contains", new Type[] { }, convertExpression);

result = Expression.Lambda<Func<TReferencedEntity, bool>>(containsExpression, entityParameter);

}
catch (Exception ex)
{
throw ex;
}

return result;
}

但是每次都测试失败,我换了线Assert.AreEqual(expected, actual);为此:Assert.AreEqual(expected.ToString(), actual.ToString());我理解它失败的原因,因为当您查看 ToString 方法的结果时,它们是不同的。

Assert.AreEqual failed.
Expected:<referencedEntity => value(Shared.Infrastructure.Test.RemoteEntityRefLoaderTest+<>c__DisplayClass13).foreignKeys.Contains(Convert(referencedEntity.Id))>.
Actual :<referencedEntity => value(System.Collections.Generic.List`1[System.Object] ) .Contains(Convert(referencedEntity.Id))>.

我只是不明白为什么...有人有关于单元测试表达式的一般提示和如何让我的特定测试通过的建议吗?

谢谢...

最佳答案

根据您发布的代码,

  • 期望值是匿名委托(delegate)/方法。 CLR 在幕后做了一些魔术来动态添加方法。以防万一。方法使用某些局部变量,CLR 创建一个新类,其中的字段设置为这些值,其中包含新的 anon 方法(以便该方法可以访问局部 var 值)。这就是您的 ..c_DisplayClass13,编译器的名称很奇怪,这样它就不会与用户定义的方法发生冲突。
  • 你的方法返回的实际值是Expression<T> .

因此.. 这两者之间的相等性检查失败了。您需要比较它们两者返回的集合的元素。所以我建议.. 将预期值和实际值都转换为列表(或更好的数据结构),然后调用采用集合参数的 NUnit 断言之一。

更新:你让我阅读了表达式树。为此 +1。
我要更改我的答案 - 通过 hack-and-assert 比较表达式树会导致脆弱的测试(例如,如果 MS 将来更改表达式树的内部结构)
表达式树只是代码块(正如我现在发现的那样),其计算结果类似于 Func<TInput,TResult) - 所以我的测试是给预期的和实际的代码块相同的输入,看看它们是否提供相同的输出。 所以我对你的测试断言是

Assert.AreEqual(expected.Compile().Invoke(inputEntity), 
actual.Compile().Invoke(inputEntity));

关于c# - 单元测试表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/821235/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com