Из списка строк в строку параметров [] - PullRequest
0 голосов
/ 10 марта 2020

У меня есть этот метод, который принимает строку параметров [] пропустить.

public static void AssertEqualProperties(this object left, object right, params string[] skip)
{
    Assert.NotNull(right, "Right compare object is null");
    Assert.NotNull(left, "Left compare object is null");

    var skipPropertyList = new List<string>(skip);

    var leftProps = left.GetType().GetProperties();
    var rightProps = right.GetType().GetProperties();

    foreach (var leftProp in leftProps)
    {
        if (ignoredProps.Contains(leftProp.Name)) continue;
        if (skipPropertyList.Contains(leftProp.Name)) continue;

        var rightProp = rightProps.FirstOrDefault(p => p.Name == leftProp.Name);
        if (rightProp == null) continue;
        var l = leftProp.GetValue(left);
        var r = rightProp.GetValue(right);
        Assert.AreEqual(leftProp.GetValue(left), rightProp.GetValue(right),
            $"Object property mismatch: {leftProp.Name} in object {left.GetType().Name}");
    }
}

Идея состоит в том, что эти параметры являются необязательными и пропускаются в тесте.

Это мое свойство:

protected virtual List<string> CreateIgnoreProperties { get; set; } = new List<string>();

У меня есть метод, который преобразует из списка строк в массив строк:

public string[] ConvertStringArrtoParamArr(List<string> CreateIgnoreProperties)
{
    var input = new List<string>();
    foreach (var prop in CreateIgnoreProperties)
    {
        input.Add(prop);
    }
    string[] output = input.ToArray();

    return output;
}

Я хочу указать CreatedParameter и этот список строк.

result.AssertEqualProperties(CreateEntity, nameof(IAuditEntity.CreatedAt), ConvertStringArrtoParamArr(CreateIgnoreProperties));

Когда я вызываю метод, хотя он говорит, не может преобразовать из строки [] в строку.

Потому что это обобщенно c Я не могу просто указать имя свойств, которые нужно игнорировать, 1 на 1.

Поэтому я пытаюсь использовать этот список logi c, где я могу пропустить и созданный объект, и свойства во всем списке. .

Ответы [ 2 ]

2 голосов
/ 10 марта 2020

AssertEqualProperties - это метод расширения, поэтому при попытке вызвать метод:

  • result равно this object left
  • CreateEntity равно object right
  • nameof(IAuditEntity.CreatedAt) - это первый элемент params string[] skip

Так что, когда вы пытаетесь передать ConvertStringArrtoParamArr(CreateIgnoreProperties), это фактически второй элемент params string[] skip, который должен быть а string не string[].

0 голосов
/ 10 марта 2020

Переработан компаратор:

public static void AssertEqualProperties(this object left, object right, params string[] skip)
        {
            Assert.NotNull(right, "Right compare object is null");
            Assert.NotNull(left, "Left compare object is null");

            var skipPropertyList = new List<string>(skip);

            var leftProps = left.GetType().GetProperties();
            var rightProps = right.GetType().GetProperties();

            foreach (var leftProp in leftProps)
            {
                if (ignoredProps.Contains(leftProp.Name)) continue;
                if (skipPropertyList.Contains(leftProp.Name)) continue;

                var rightProp = rightProps.FirstOrDefault(p => p.Name == leftProp.Name);
                if (rightProp == null) continue;

                if(leftProp.PropertyType != rightProp.PropertyType ) continue;

                var leftValue = leftProp.GetValue(left);
                var rightValue = rightProp.GetValue(right);
                if (leftProp.PropertyType.Name.ToLower() != "string" && leftValue is IEnumerable leftList && rightValue is IEnumerable rightList)
                {
                    IEnumerator leftEnumerator, rightEnumerator;
                    for (leftEnumerator = leftList.GetEnumerator(), rightEnumerator = rightList.GetEnumerator();
                        leftEnumerator.MoveNext() && rightEnumerator.MoveNext();)
                    {
                        if (leftEnumerator.Current?.GetType().Namespace != null && leftEnumerator.Current.GetType().Namespace.StartsWith("Intent2."))
                        {
                            leftEnumerator.Current.AssertEqualProperties(rightEnumerator.Current, skip);
                        } else 
                            Assert.AreEqual(leftEnumerator.Current, rightEnumerator.Current, $"Object collection property mismatch: {leftProp.Name} in object {left.GetType().Name}");
                    }
                }
                else
                {
                    if (leftProp.PropertyType.Namespace != null && leftValue != null &&
                        leftProp.PropertyType.Namespace.StartsWith("Intent2."))
                    {
                        leftValue.AssertEqualProperties(rightValue, skip);
                    }
                    else
                        Assert.AreEqual(leftValue, rightValue,
                            $"Object property mismatch: {leftProp.Name} in object {left.GetType().Name}");
                }
            }
        }

Я добавил IAuditEntry в список строк, которые будут моими параметрами:

        var ignoreList = new List<string>(CreateIgnoreProperties);
        ignoreList.Add(nameof(IAuditEntity.CreatedAt));

Затем я вызываю

  result.AssertEqualProperties(CreateEntity, ignoreList.ToArray());

У компаратора возникли проблемы при сравнении двух классов. Если у них были классы внутри и списки, то сравнивались ссылки, а не значения. Из-за разных ссылок объекты не были равны.

Другой проблемой было сравнение списков. Списки также могут содержать классы. Нам пришлось покрыть оба сценария ios.

Теперь все работает нормально.

Спасибо всем за ваш вклад.

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