Как проверить две возвращенные функции с разными значениями аргументов в JavaScript? - PullRequest
0 голосов
/ 28 июня 2019

У меня есть функция, которая возвращает сравнение. Функция

  getComparisonFunction(propertyOfComparison) {
    const func = function(a, b){
      if ( a[propertyOfComparison] < b[propertyOfComparison] ) {
        return -1;
      }
      if ( a[propertyOfComparison] > b[propertyOfComparison] ) {
        return 1;
      }
      return 0;
    };

    return func;
  }

Этот метод будет использоваться внутри метода сортировки javascript.например:

arrayOfObjects.sort(getComparisonFunction('name'));

Этот метод будет сортировать «arrayOfObjects» по свойству «name».Метод работает нормально, вопрос: как я могу сравнить вызов функции с разными аргументами

  it('should get correct comparison function', function () {
    const func = component.getComparisonFunction('testProperty');

    const expectedFunc = function(a, b){
      if ( a['testProperty'] < b['testProperty'] ) {
        return -1;
      }
      if ( a['testProperty'] > b['testProperty'] ) {
        return 1;
      }
      return 0;
    };

    expect(func.toString()).toEqual(expectedFunc.toString());
  });

Это то, что у меня сейчас, но это не работает.Ошибка, которую я получаю после запуска кода:

 Expected 'function (a, b) {
                if (a[propertyOfComparison] < b[propertyOfComparison]) {
                    return -1;
                }
                if (a[propertyOfComparison] > b[propertyOfComparison]) {
                    return 1;
                }
                return 0;
            }' to equal 'function (a, b) {
                if (a['testProperty'] < b['testProperty']) {
                    return -1;
                }
                if (a['testProperty'] > b['testProperty']) {
                    return 1;
                }
                return 0;
            }'.

Ответы [ 2 ]

2 голосов
/ 28 июня 2019

Проверка кода функции в виде теста очень хрупкий и легко ломается, давая вам ложный отрицательный результат:

let someFn = function(a, b) {
  return a + b;
}

let expected = `function(a, b) {
  return a + b;
}`

console.log("Test original implementation:", test(someFn.toString(), expected));

//later the code style is changed to remove extra whitespace and make it one line
someFn = function(a, b) { return a+b; }

console.log("Test updated implementation:", test(someFn.toString(), expected));

//simple testing
function test(expected, actual) {
  return expected == actual
}

Простое внесение нефункциональных изменений в код нарушает тест.

Еще хуже, если являются функциональными изменениями в коде, тест не может гарантировать, что новая реализация ведет себя так же, как и старая, поскольку она смотрит только на структуру кода:

//simplified case of what the actual code could be doing
function someCodeBaseFunction() {
  let someInput = [8, 12, 42];
  return someFn(...someInput)
}

let someFn = function(a, b) { return a+b; }

let expected = `function(a, b) { return a+b; }`

console.log("Test original implementation:", test(someFn.toString(), expected));

console.log("Codebase usage:", someCodeBaseFunction()); //20, as the third number is ignored

//new implementation
someFn = function(...args) { 
  return args.reduce((a, b) => a + b); 
}

//update the test, so it passes
expected = `function(...args) { 
  return args.reduce((a, b) => a + b); 
}`

console.log("Test updated implementation:", test(someFn.toString(), expected));

//some existing line of code
console.log("Codebase usage:", someCodeBaseFunction()); //62, as the third number is now used

//simple testing
function test(expected, actual) {
  return expected == actual
};

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

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

//arrange
input = [
 {testProperty: "c", id: 1},
 {testProperty: "a", id: 2},
 {testProperty: "d", id: 3},
 {testProperty: "b", id: 4}
];

expected = [
 {testProperty: "a", id: 2},
 {testProperty: "b", id: 4},
 {testProperty: "c", id: 1},
 {testProperty: "d", id: 3}
];

//act
input.sort(component.getComparisonFunction('testProperty'))

//assert
expect(input).toEqual(expected);

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

//arrange
a = { testProperty: "a" };
b = { testProperty: "B" };

//act
result = component.getComparisonFunction('testProperty')(a, b)

//assert
expect(result).toBeGreaterThanOrEqual(1)

Или без учета регистра:

//arrange
a = { testProperty: "a" };
b = { testProperty: "B" };

//act
result = component.getComparisonFunction('testProperty')(a, b)

//assert
expect(result).toBeLessThanOrEqual(-1)

Это определяет ваши ожидания гораздо более четко и гарантирует, что будущие изменения покроют именно то, что вам нужно.

0 голосов
/ 28 июня 2019

Если вы хотите выполнить сортировку с помощью любого предоставленного параметра, вы можете попробовать следующее:

const array=[
  {name:'C',Key:'14',val:3},
  {name:'B',Key:'12',val:2},
  {name:'A',Key:'11',val:1},
  {name:'D',Key:'16',val:4},
  {name:'E',Key:'18',val:5}
];

console.log(array);

function comparer(prop){
  return function(a,b){
    return a[prop]-b[prop];
  }
};
array.sort(comparer('Key'));
console.log(array);
array.sort(comparer('val'));
console.log(array);

Более того, чтобы протестировать его, просто используйте тестовые примеры, как указано выше, и проверьте, соответствует ли его сортировка вашей реализации.

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