@fryette

Как пройти такой unit test?

[TestMethod]
 public void FunctionExtention_CombinePredicates_Should_Avoid_Closure()
        {
            var value = 0;
            var predicates = new Predicate<int>[]
            {
                x => x > value
            };
            var result = FunctionExtentions.CombinePredicates(predicates);
            value = 1000; // This should not affect the call above!
            Assert.IsTrue(result(2));
            Assert.IsTrue(result(5));
            Assert.IsTrue(result(1000));
            Assert.IsFalse(result(-20));
            Assert.IsFalse(result(0));
            Assert.IsFalse(result(-1000));
        }
        public static Predicate<T> CombinePredicates<T>(Predicate<T>[] predicates)
        {            
            return item => predicates.All(predicate => predicate(item));
        }
  • Вопрос задан
  • 2535 просмотров
Решения вопроса 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
Без читов точно не пройти! :-)

Странный вопрос. Запустить проект, в котором размещен этот тест и посмотреть на отчет.
Если будут ошибки, внеси соответствующие исправления в код. Обычно это делается так.

----------
Подведу итоги по результатам дискуссии в комментариях.

1. Простые/тупые варианты пройти тест успешно, по крайней мере технически, это внести изменения в данные:

return x > value - 1000; // убираем лишнюю тысячу :)

return x + 1000 > value; // добавляем

2. Самый очевидный и, более ли менее правильный вариант, по крайней мере на практике (хотя лучше вообще избегать таких ситуаций), использовать дополнительную переменную для сохранения значения:

var value = 0;
var value2 = value;
var predicates = new Predicate[]
{
  x => x > value2
};


3. Еще могу предложить построить дерево. Но это сложное решение, кода больше. Хотя, если вы проходили/изучаете именно эту тему, то вполне возможно, что этот вариант может быть правильным.

// using System.Linq.Expressions;

[TestMethod]
public void FunctionExtention_CombinePredicates_Should_Avoid_Closure()
{
    var value = 0;

    var iks = Expression.Parameter(typeof(int), "x");
    var v = Expression.Constant(value, typeof(int)); // фиксируем значение value 
    var less = Expression.LessThan(v, iks);
    var l = Expression.Lambda<Func<int, bool>>(less, new ParameterExpression[] { iks }).Compile();

    var predicates = new Predicate<int>[]
    {
      x => l(x)
    };
    var result = FunctionExtentions.CombinePredicates(predicates);
    value = 1000; // This should not affect the call above!
    Assert.IsTrue(result(2));
    Assert.IsTrue(result(5));
    Assert.IsTrue(result(1000));
    Assert.IsFalse(result(-20));
    Assert.IsFalse(result(0));
    Assert.IsFalse(result(-1000));
}

public static Predicate<T> CombinePredicates<T>(Predicate<T>[] predicates)
{            
    return item => predicates.All(predicate => predicate(item));
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы