Output pengujian Ruby minitest dari metode yang memerlukan input pengguna

TERSELESAIKAN


Pertanyaan 1: Saya ingin menulis tes untuk file_choice_reader di kelas berikut.

Kelas mencetak daftar file dengan tipe tertentu ke baris perintah dan memungkinkan pengguna memilih salah satu dengan mengetikkan nomor indeks.

class File_chooser

  #shortened for readability

  def file_choice_suggester
    file_list = file_list_generator
    if file_list.count > 0
      file_list.each_with_index do |file, index|
        puts index.to_s + ' ' + file
      end
    else 
      puts 'Neither .fcv nor .tmpl nor .ipa nor .apf files in directory.'  
    end
    file_list
  end

  def file_choice_reader
    unless File.exists? 'Cookie.txt'
      file_list = file_choice_suggester
      puts 'Choose file by typing index number!'
      chosen_file = STDIN.gets.chomp
      if /[^0-9]/.match(chosen_file) || chosen_file.to_i >= file_list.count
        abort ('No valid index number.')
      else 
        chosen_file = chosen_file.to_i
      end
      cookie_writer(  file_list[chosen_file].to_s )
      system 'cls'
      puts 'You chose file: ' + file_list[chosen_file].to_s
      path_and_file = file_list[chosen_file].to_s
    else
      self.hints_hash = hints_hash.merge( 'cookie_del' => '* Change file by typing command: del Cookie.txt *' )
      pre_chosen_file = File.read('Cookie.txt')
      path_and_file = pre_chosen_file.chomp.to_s
    end
    path_and_file
  end

end

Pengujian saya terlihat seperti ini (saya diminta mengetikkan nomor indeks tetapi masih dikatakan bahwa outputnya adalah ""):

class TestFile_chooser < MiniTest::Unit::TestCase 
  def setup
    @file_chooser = File_chooser.new
  end

  def test_file_choice_reader_produces_confirmation_output
    assert_output( /You chose file/ ) { @file_chooser.file_choice_reader }
  end 
end

Output dari file_choice_reader selalu "". Bagaimana saya bisa menambahkan urutan mendapatkan input pengguna dan/kemudian/ mengukur output?

Pertanyaan 2: Ini adalah pertanyaan singkat. Kelas tes yang sama seperti di atas juga berisi

  def test_file_choice_suggester_produces_output
    assert_output( /apf|fcv|tmpl|ipa/ ) {  @file_chooser.file_choice_suggester }
  end 

Ujian ini berhasil. Tapi itu meninggalkan saya dengan "1 kali berjalan, 2 pernyataan". Itu membuatku bingung. Bagaimana 1 pengujian dalam 1 kali proses menghasilkan 2 (??) pernyataan?

Saya akan sangat senang jika mendapat bantuan. Pembahasan sekecil apapun di internet sepertinya tidak membahas hal-hal tersebut. Mungkin itu terlalu mendasar?

(Saya juga berterima kasih atas semua komentar lain tentang kode di komentar. Terima kasih telah membantu.)


PEMBARUAN (Pertanyaan 1)

Dengan bantuan balasan di bawah ini, pengujian versi terbaru saya menggunakan contoh di http://www.ruby-doc.org/core-2.1.5/Module.html

@file_chooser.instance_eval do 
  self.create_method( :puts ) {|arg| printed = arg} 
end

Tes berjalan tanpa kesalahan... TAPI... MASIH memberitahu saya: "Sanggahan gagal. Tidak ada pesan yang diberikan."

Terima kasih atas bantuannya sejauh ini! Terima kasih juga atas semua petunjuk bagaimana cara mengetahuinya.

[Menambahkan kode di sini sulit dibaca di komentar.]


PEMBARUAN 2 (Pertanyaan 1)

Saya mengikuti saran pada pertanyaan berbeda untuk secara eksplisit memerlukan permata terkecil. Saya meletakkan ini di atas kode testfile saya:

require 'rubygems'
gem 'minitest'
require 'minitest/autorun'
require_relative 'falcon'

(Jika ini berlebihan, harap beri tahu saya.)

Kode tes berikut sekarang tidak lagi menghasilkan kesalahan atau kegagalan:

  def test_file_choice_suggester_produces_output
    assert_output( /apf|fcv|tmpl|ipa/ ) {  @file_chooser.file_choice_suggester }
  end 

Terima kasih atas bantuan Anda!


person enahel    schedule 11.11.2014    source sumber
comment
#2 ini mungkin ada hubungannya dengan metode assert_output yang membuat banyak pernyataan. Atau jika Anda memiliki kedua tes ini dalam file yang sama.   -  person Josh Bodah    schedule 12.11.2014
comment
Mengenai gaya, saya merekomendasikan panduan gaya GitHub: github.com/styleguide/ruby   -  person Josh Bodah    schedule 12.11.2014
comment
#1 Tidak yakin apa pertanyaannya sebenarnya, tetapi harus mematikan input pengguna atau meneruskan aliran input sebagai argumen atau semacamnya   -  person Josh Bodah    schedule 12.11.2014
comment
Terima kasih! Pertanyaannya adalah: bagaimana cara menulis tes yang memastikan pengguna saya mendapat pesan konfirmasi. Outputnya bukan output langsung dari metode ini tetapi hanya muncul setelah pengguna memasukkan ke sdtin. Tes saat ini memberi tahu saya bahwa metode tersebut menghasilkan string kosong. Ini tidak terjadi setelah masukan pengguna. Bagaimana saya perlu menulis tes? (Saya harap ini lebih jelas.)   -  person enahel    schedule 12.11.2014


Jawaban (1)


Untuk #1:

Salah satu pendekatannya adalah dengan mematikan objek IO yang digunakan pengujian Anda dengan mengganti metode puts. Cara lainnya adalah dengan memfaktorkan ulang desain Anda sehingga metode Anda lebih kecil dan lebih mudah untuk diuji.

Penggantian puts akan menjadi seperti ini:

Dalam pengujian Anda:

@file_chooser = File_chooser.new
printed = nil
@file_chooser.instance_eval do
  # Open up the instance and stub out the puts method to save to a local variable
  define_method :puts, Proc.new {|arg| printed = arg}
end
# Run code
refute printed.nil?

Alternatifnya, Anda dapat menjalankan ekspektasi pada objek $STDOUT untuk memastikan objek tersebut mendapat panggilan yang benar (lihat Mocha untuk Ruby)

person Josh Bodah    schedule 12.11.2014
comment
Terima kasih! Sayangnya ini tidak berhasil untuk saya. Pesan kesalahannya adalah:falcon_test.rb:90: kesalahan sintaksis, '{' yang tidak terduga, mengharapkan kata kunci_end definisikan metode_, :puts {|arg| print = arg} ^ falcon_test.rb:90: kesalahan sintaksis, tak terduga '}', mengharapkan kata kunci_end falcon_test.rb:116: kesalahan sintaksis, $end tak terduga, mengharapkan kata kunci_end - person enahel; 13.11.2014
comment
Saya memasukkan kode ke dalam tes def .... end. Tidak yakin apa yang saya lakukan salah. Terima kasih telah membalas. - person enahel; 13.11.2014
comment
Maaf, saya mengacaukan sintaksisnya. Coba sekarang - person Josh Bodah; 14.11.2014
comment
Terima kasih! Setelah membaca tentang bagaimana mendefinisikan_metode bersifat pribadi dan mengulangi peretasan di halaman ini ruby- doc.org/core-2.1.5/Module.html, pengujian berjalan tanpa kesalahan: @file_chooser.instance_eval do self.create_method( :puts ) {|arg| print = arg} end ... TAPI ... MASIH memberitahu saya bahwa output saya adalah: Di stdout. /apf|fcv|tmpl|ipa/ diharapkan cocok. Terima kasih sejauh ini. Saya pasti belajar sesuatu. Berterima kasih atas semua petunjuk bagaimana cara mengetahuinya! - person enahel; 15.11.2014
comment
Maaf, pesan kesalahan tercampur. Pesannya adalah: Sanggahan yang gagal. Tidak ada pesan yang diberikan. - person enahel; 15.11.2014
comment
Di atas saya menambahkan kode yang sekarang berfungsi. Sepertinya masalah saya terkait dengan tidak memanggil permata terkecil secara eksplisit. Terima kasih atas bantuan Anda. - person enahel; 01.12.2014