Как предотвратить переопределение классов в Ruby?

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

Например, у меня есть класс в папке lib, КлассПример. У него есть публичный метод сделай что-нибудь с собственной логикой. В минитесте кто-то может захотеть переопределить этот метод другой логикой. Я хочу запретить запуск теста, если логика класса была переопределена.

Примеры кода:

lib/klass_example.rb

class KlassExample

  def do_something
    false
  end

end

тест/модуль/lib/klass_example_test.rb

require 'unit/test_helper'
require 'klass_example'

class KlassExample

  def do_something
    true
  end

end

class KlassExampleTest < Minitest::Test

  def test_do_something
    assert_equal true, KlassExample.new.do_something
  end

end

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

Есть ли возможное комплексное решение, как это сделать?

Ваш вопрос не ясен. Вы никогда ничего не переопределяете в своих примерах кода.

Jörg W Mittag 23.05.2019 16:25

Вы также не должны использовать макет для этого! Поскольку KlassExample является объектом тестирования, вы должны напрямую проверять его поведение.

Tom Lord 23.05.2019 17:31

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

Tom Lord 23.05.2019 17:33
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
0
3
216
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хотя этот конкретный вариант использования может быть частично покрыт TracePoint#new(:class), установив TracePoint при повторном открытии класса и, например. поднимаясь оттуда, вы никогда не помешаете все возможностям, явно и неявно встроенным в Ruby, действительно разрешать разработчикам делать все, что они хотят.

Перезаписанный обратный вызов Module#prepended не позволит другим prepend модулям вашего класса:

KlassExample.prepend(Module.new { def self.prepended(*); raise end })

Есть способы предотвратить вызовы Module#define_method, и они уже выглядят как хаки.

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

Ruby — это не язык, предназначенный для того, чтобы разработчики не допустить делали все, что хотят.

Другие вопросы по теме