문제

최근에 표현 트리를 만들어야하여 같은 테스트 방법을 작성해야합니다 ...

    /// <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));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top