Следует ли проверять возвращаемый тип методов в модульном тестировании слабо типизированных языков? - PullRequest
0 голосов
/ 18 октября 2018

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

В свободно типизированных языках, таких как Ruby, JavaScript, Python и т. Д., Все может быть возвращено.Имеет ли смысл написать модульный тест, который проверяет тип объекта, возвращаемого методом?Это, на мой взгляд, гарантирует, что логическое значение будет возвращено там, где ожидается логическое значение.

Нужно ли даже проводить юнит-тест ниже?

=============================

Попытка на примере Ruby:

first_module.rb:

module FirstModule
  TypeA = Struct.new(
    :prop1,
    :prop2)

  self.create_type_a
    TypeA.new(
      'prop1Val',
      'prop2Val')
  end
end

type_a_repository.rb:

module TypeARepository
  def self.function_to_test
    FirstModule.create_type_a  # This will return TypeA object
  end
end

type_a_repository_spec.rb:

RSpec.describe '' do
  describe '' do
    before do
      allow(FirstModule).to receive(:create_type_a)
          .and_return(FirstModule.create_type_a)
    end

    it '' do
      result = TypeARepository.function_to_test
      expect(result).to be_a(FirstModule::TypeA) # is this necessary?
    end
  end
end

1 Ответ

0 голосов
/ 18 октября 2018

Если вы используете программирование по контракту , то ответ обычно «нет», поскольку возвращаемое значение соответствует ожидаемым критериям, которые зачастую действительно бесполезны, тогда вы не можете жаловаться.

Например:

# Adds together zero or more integer values and returns the sum
def sum(*numbers)
  numbers.inject(0,:+)
end

При тестировании вы должны сделать что-то вроде этого:

assert_equal 0, sum
assert_equal 1, sum(1)
assert_equal 0, sum(1, -1)

Что теперь происходит, когда вы вводите нецелые значения?

sum('1')
# => Exception: String can't be coerced into Integer

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

# Adds together zero or more numerical values and returns the sum
def sum(*numbers)
  numbers.map(&:to_i).inject(0,:+)
end

Теперь вы можете сложить нецелые значения:

assert_equal 6, sum(1, 2.0, '3')

Обратите внимание, что все время, пока результат проходит проверку утвержденияты доволен.В Ruby 6.0, 6 и "6" все разные, неэквивалентные, поэтому не стоит беспокоиться о получении неправильного типа.

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

assert_equal "this is amazing", "this is " + amazing_string_result

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

Это часто входит в игру, когда выхотите литеральное true или false вместо некоторого правдивого значения, такого как 1:

assert_true some_method?(:value)

Где, если это возвращает правдивое , но не буквальноеtrue значение, что контракт расторгнут и потерпел неудачу.

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

assert_equal 6, 1 + 2 + 3
assert_equal 6, 6
assert_equal 6, '6'.to_i
assert_true true

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

Лучшие модульные тесты:

  • Продемонстрируйте, каким должен быть кодиспользуется для четкого описания ожиданий для входов и выходов.
  • Идентификация и проверка поведения при любых и всех граничных условиях, относящихся к решаемой проблеме.
  • Иллюстрируйте режимы отказа, когда код используется в неправильномспособы, которыми должен быть явно запрещен.
  • Избегайте демонстрации всех бесконечных способов, которыми код не будет работать.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...