Я бы сначала проверить, не случайный выбор одной строки из файла в одну строку, то я бы проверить выбор строки из файла многострочного , тогда я бы проверил, что выбор случайный. Вы не можете проверить хаотичность в конечное время, поэтому лучшее, что вы можете сделать, это
- теста, что ваш метод возвращает значение в желаемом диапазоне, зная, что, так как ваш тест будет работать много, много раз в течение в течение жизни вашего приложения вы, вероятно, узнаете, когда-нибудь выйдет что-то вне диапазона, и
- докажите, что ваш код использует источник случайности.
Предположим, что файл не существует в тестовой среде, или вы не знаете его содержимого, или не хотите, чтобы его асимметрия была правильной для одного теста и некорректна для других, поэтому нам нужно предоставить способ тестирования для класса в разных файлах.
Мы могли бы написать следующее, написание одного теста за раз, заставляя его проходить и рефакторинг, прежде чем писать следующее. Вот тесты и код после третьего тест написан, но прежде, чем это было реализовано:
спецификации/модель/thing_spec.rb
describe Thing do
describe '.random_select' do
it "returns a single line from a file with only one line" do
allow(Thing).to receive(:file) { "spec/models/thing/1" }
expect(Thing.random_select).to eq("Thing 1")
end
it "returns a single line from a file with multiple lines" do
allow(Thing).to receive(:file) { "spec/models/thing/2" }
expect(Thing.random_select).to be_in(['Thing 1', 'Thing 2'])
end
it "returns different lines at different times" do
allow(Thing).to receive(:file) { "spec/models/thing/2" }
srand 0
thing1 = Thing.random_select
srand 1
thing2 = Thing.random_select
expect(thing1).not_to eq(thing2)
end
end
end
приложения/модель/thing.rb
class Thing
def self.random_select
"Thing 1" # this made the first two tests pass, but it'll need to change for all three to pass
end
def self.file
"lib/things"
end
end
Когда я написал второй тест, я понял, что он прошел без каких-либо дополнительных изменений кода, поэтому я решил удалить его. Но я отложил это решение, написал третий тест и обнаружил, что, как только третий тест пройдет второй, будет иметь значение, так как второй тест проверяет, что значение получено из файла, но третий тест этого не делает.
be_in
это красивый способ, чтобы проверить, что возвращаемое значение в известном наборе чем include
, поскольку он ставит фактическое значение внутри expect
где RSpec ожидает.
Существуют и другие способы контроля случайности, поэтому вы можете проверить, что она используется. Например, если вы использовали sample
, вы могли бы allow_any_instance_of(Array).to receive(:sample)
и вернуть все, что захотите. Но мне нравится использовать srand
, поскольку для реализации не требуется использование определенного метода, использующего генератор случайных чисел.
Если файл может отсутствовать или пуст, вам также нужно будет его проверить.
Является ли файловая часть (например, отправленной) системой, которую вы тестируете, и имеет ли она известный контент? Или он предоставляется пользователем и может содержать что угодно? –