Модульное тестирование интерфейса командной строки

#ruby #unit-testing #command-line-arguments

#ruby #модульное тестирование #аргументы командной строки

Вопрос:

Я использую clamp — фреймворк командной строки для моего приложения ruby и не уверен, как инициировать мои объекты clamp для модульного тестирования. Мой объект clamp выглядит следующим образом

 class myCommand < Clamp::Command
  parameter "first", "first param"
  parameter "second", "second param"

  def execute
    #Data
  end
end
  

И запускается через командную строку следующим образом

 $~> myCommand first second
  

На данный момент в моих тестах rspec мне приходится устанавливать свойства объектов напрямую, вот так.

   before(:each) do
   $stdout = StringIO.new
   @my_command = myCommand.new("")
   @my_command.first= "first"
   @my_command.second= "second"
 end
  

Похоже, что это неподходящий способ инициировать объекты clamp для тестирования, но я не уверен в правильном способе сделать это. Интересно, есть ли у кого-нибудь какие-нибудь идеи. Спасибо

Ответ №1:

Итак, то, что вы делаете, это:

  • создание экземпляра команды
  • настройка атрибутов на нем
  • вызов #execute

Это прекрасный способ протестировать команду Clamp и, вероятно, лучший способ модульного тестирования логики вашего #execute метода.

Если вы хотите протестировать синтаксический анализ аргументов командной строки, вы могли бы использовать #parse метод и проверить значения атрибутов, например

 before do
  @command = MyCommand.new("my")
end

describe "#parse" do

  before do
    @command.parse(["FOO", "BAR"])
  end

  it "sets attribute values" do
    @command.first.should == "FOO"
    @command.second.should == "BAR"
  end

end
  

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

Если вы хотите протестировать синтаксический анализ и выполнение одновременно, попробуйте что-то вроде:

 describe ".run" do
  context "with two arguments" do
    it "does something useful" do
      MyCommand.run("cmd", ["ARG1", "ARG2"])
      # ... test for usefulness
    end
  end
end
  

Опять же, способ, которым вы сейчас тестируете, совершенно хорош. Я надеюсь, что это поможет.

Комментарии:

1. Отличный ответ, именно то, что я искал. Меня интересует только тестирование кода в методе execute, поэтому я искал более чистый способ инициализации моего командного объекта в методе «before». Я буду использовать @command.parse, чтобы помочь мне сделать это.