Я устанавливаю правила написания минитестов и хочу, чтобы другие программисты не переопределяли методы для существующих классов, потому что это повлияет на другие тесты, где этот класс будет использоваться. Вот некоторые пояснения ниже.
Например, у меня есть класс в папке 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
Я хочу, чтобы программисты использовали Минитест:: Макет вместо переопределения класса, поэтому мне нужны какие-то принудительные действия, чтобы заставить их писать код правильным образом.
Есть ли возможное комплексное решение, как это сделать?
Вы также не должны использовать макет для этого! Поскольку KlassExample является объектом тестирования, вы должны напрямую проверять его поведение.
Вместо того, чтобы придумывать какое-то сложное/запутанное решение, я всегда решал это с помощью проверки кода. Должно быть совершенно очевидно, если что-то переопределение метода внутри теста. Также есть это правило рубокопа, чтобы помочь предотвратить такую плохую практику, хотя я не уверен, есть ли эквивалентный полицейский для минитеста.

Хотя этот конкретный вариант использования может быть частично покрыт TracePoint#new(:class), установив TracePoint при повторном открытии класса и, например. поднимаясь оттуда, вы никогда не помешаете все возможностям, явно и неявно встроенным в Ruby, действительно разрешать разработчикам делать все, что они хотят.
Перезаписанный обратный вызов Module#prepended не позволит другим prepend модулям вашего класса:
KlassExample.prepend(Module.new { def self.prepended(*); raise end })
Есть способы предотвратить вызовы Module#define_method, и они уже выглядят как хаки.
Но весь набор возможностей обмануть вашу охрану практически безграничен, так что сомневаюсь, что это вообще выполнимо. Бьюсь об заклад, каждый раз, когда вы будете думать «хорошо, теперь все прикрыто», я легко изобрету еще один громоздкий способ обойти всех ваших охранников.
Ruby — это не язык, предназначенный для того, чтобы разработчики не допустить делали все, что хотят.
Ваш вопрос не ясен. Вы никогда ничего не переопределяете в своих примерах кода.