Выполните Assert.AreMatch () для глубокого сравнения свойств в двух объектах. - PullRequest
6 голосов
/ 17 августа 2010

Я пишу тесты против нашего механизма кэширования и хочу быть уверенным, что то, что входит в кеш, совпадает с тем, что выходит, то есть все свойства совпадают. Вот вымышленный пример того, как я бы хотел, чтобы он работал

    [Test]
    public void add_client_model_member_to_cache_then_retreve()
    {
        //arrange
        MemcachedClient client = new MemcachedClient();
        Member member = GetMember();
        client.Store(StoreMode.Set, "membertest", member);

        // act
        var result = client.Get<Member>("membertest");

        // assert
        Assert.AreMatch(result, member);
    }

Невозможно выполнить Assert.AreEqual для каждого свойства, так как будет много таких тестов со многими свойствами в каждом.

Ого, спасибо Джон. Я думаю, что вы ответили менее чем за минуту. Вот мое окончательное решение для любых заинтересованных сторон. Я реализовал так, как предложил Джон (я думаю), однако у меня возникли небольшие проблемы со свойствами массива, и поэтому мое решение обрабатывает только массивы целых чисел (все, что мне сейчас нужно).

Это также должно быть довольно скользким спуском, если я попытаюсь проверить глубже, чем один уровень. Я уверен, что это может быть достигнуто, однако для моих целей это не требуется.

private bool AreMatch(object initial, object result)
    {
        if (initial.Equals(result)) 
            return true;

        foreach (var property in initial.GetType().GetProperties())
        {
            var initialPropValue = property.GetValue(initial,null);
            var resultPropValue = result.GetType().GetProperty(property.Name).GetValue(result,null);

            if (property.PropertyType.IsArray)
            {
                if ((initialPropValue != null && resultPropValue != null) && !Enumerable.SequenceEqual((int[])initialPropValue, (int[])resultPropValue))
                        return false;                   
            }
            else if (!object.Equals(initialPropValue, resultPropValue))
            {
                return false;
            }
            else if (initialPropValue != null && property.PropertyType.IsClass)
            {
                // Don't go deeper than one level, this got me into trouble
                //if (!AreMatch(initialPropValue, resultPropValue))
                //  return false;
            }
        }
        return true;
    }

Метод, описанный выше, можно использовать в следующих ситуациях

    [Test]
    public void cached_result_is_same_as_original()
    {
        //arrange
        Member member = GetMember();
        client.Store(StoreMode.Set, "membertest", member);

        // act
        var result = client.Get<Member>("membertest");

        // assert
        Assert.IsTrue(AreMatch(member, result));
    }

    [Test]
    public void cached_result_is_same_as_original()
    {
        //arrange
        Member member = GetMember();
        client.Store(StoreMode.Set, "membertest", member);

        // act
        var result = client.Get<Member>("membertest");
        result.FirstName = "Result is different"; 

        // assert
        Assert.IsFalse(AreMatch(member, result));
    }

1 Ответ

4 голосов
/ 17 августа 2010

Что ж, вы, конечно, могли бы написать что-нибудь, чтобы пройти через все свойства, и вызвать object.Equals в результате извлечения значения свойства из ожидаемых и фактических. Используйте Type.GetProperties() для получения самих свойств и PropertyInfo.GetValue для получения значения.

Это будет несколько грубо, но вы всегда можете настроить его при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...