У меня есть тест, который я могу написать с помощью метода receive () с аргументом block для пользовательской проверки таких аргументов, как этот:
expect(provider).to receive(:shell_out!) do |*args|
expect(args.flatten.compact.map(&:to_s)).to eql(["useradd", "-m", "adam"])
end
У меня есть сотни таких тестов, и я хотел бычтобы сократить это до:
expect(provider).to receive(:shell_out!).with_flat_compact_str("useradd", "-m", "adam")
В настоящее время я иду по пути создания обезьяньего патча в пользовательском методе, чтобы реализовать его в классе RSpec::Mocks::MessageExpectation
, и мне интересно, есть ли более простой способ получитьчто я хочу?
Обратите внимание, что цель этого заключается в том, чтобы API shell_out!(*args)
взял свои аргументы-сплат и запустил над ними args.flatten.compact.map(&:to_s)
, и я хочу разрешить устанавливать ожидания для сообщения, которое не будетпотерпеть неудачу, если вызывающий объект вносит несущественные изменения в вызов (т. е. рассматривает shell_out!(a, b, c)
и shell_out!(a, nil, [b, c])
как одно и то же. Я также явно не хочу вызывать его одним методом, а затем настраивать ожидание для внутреннего вызова API после того, как сплат имеетбыл нормализован.
Также обратите внимание, что я пошел по дороге, пытаясь написать собственный сопоставитель, который выглядел так:
receive(:shell_out).with(flat_compact_str("useradd", "-m", "adam"))
Я обнаружил, что это Доуне работает с аргументами сплат (по крайней мере, я не мог понять это).Это работало бы, если бы был один аргумент, который был Массивом, но не через все аргументы.В сплат-аргах есть особая магия.