단위 테스트 발현 나무
-
03-07-2019 - |
문제
최근에 표현 트리를 만들어야하여 같은 테스트 방법을 작성해야합니다 ...
/// <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))>.
왜 그런지 이해하지 못합니다 ... 단위 테스트 표현식에 대한 일반적인 팁과 제안 사항에 대한 일반적인 팁이 있습니까? 특정 테스트를 통과하는 방법은 무엇입니까?
감사...
해결책
게시 한 코드를 기반으로
- 예상 값은 익명 대의원/방법입니다. CLR은 현장 뒤에 약간의 마법을 사용하여 메소드를 즉석에 추가합니다. Anon의 경우. 메소드는 특정 로컬 변수를 사용하고 CLR은이 값으로 필드가 설정된 새 클래스를 생성하고 새로운 ANON 메소드가 그 안에있어서 로컬 VAR 값에 액세스 할 수 있도록합니다. 그래서 그것은 당신의 ..c_displayclass13입니다. 이상한 이름을 가진 컴파일러가있는 사용자 정의 메소드와 충돌하지 않도록하십시오.
- 방법에 의해 반환 된 실제 값은 an입니다
Expression<T>
.
그러므로 ..이 두 사람 사이의 평등 점검은 실패합니다. 두 가지 컬렉션의 요소를 비교해야합니다. 따라서 예상 값과 실제 값을 목록 (또는 더 나은 데이터 구조)으로 변환 한 다음 수집 매개 변수를 취하는 Nunit의 어서 중 하나를 호출합니다.
업데이트: 당신은 내가 표현 나무를 읽게되었다. 그것을 위해 +1.
나는 내 대답을 바꿀 것입니다-해킹 및 해킹을 통해 표현식 트리를 비교하면 연약한 테스트로 이어질 것입니다 (예 : MS가 미래에 발현 트리의 내부 구조를 변경하면)
표현 나무는 단지 코드 블록 (지금 알았 듯이) 일뿐입니다. Func<TInput,TResult)
- 내 테스트는 예상 및 실제 코드 블록에 동일한 입력을 제공하고 동일한 출력을 제공하는지 확인하는 것입니다. 그래서 당신의 시험에 대한 나의 주장은 될 것입니다
Assert.AreEqual(expected.Compile().Invoke(inputEntity),
actual.Compile().Invoke(inputEntity));