Zanim odpowiem na pytanie, jak to zrobić w Ruby, chciałbym wyjaśnić kilka nieporozumień.
Po pierwsze, nie powiedziałbym, że istnieje "sposób Rubinowy" testów takich rzeczy, podobnie jak nie ma ścisłego sposobu testowania czegoś takiego w .NET (co, wprawdzie nie używam od lat) . Można zastosować podejście oparte na interakcji (szydercze) lub, jak już powiedziałeś, przyjąć bardziej podejście oparte na stanie, tworząc test integracji, który wykonuje wszystkie trzy klasy jednocześnie. Kompromisy między tymi dwoma podejściami są, moim zdaniem, agnostyczne. Ruby hasmanymockingframeworks który pozwoliłby ci zastosować podejście oparte na interakcji, jeśli jest to najbardziej wygodne. (Zazwyczaj używam tego, który jest dostarczany z RSpec.)
Po drugie, nie uważam, że "w tym moduły nad iniekcją konstruktora" jest dokładnym stwierdzeniem. Moduły są dodatkowym narzędziem dostępnym w Ruby, ale nie zastępują dobrego projektu OO kompozycją obiektów. Przez cały czas przekazuję zależności do moich inicjalizatorów w Ruby, ponieważ ułatwia to ich testowanie i wielokrotne użycie. Generalnie domyślnie będę zależał od listy argumentów, ale tak jak def initialize(converter=CodeConverter.new)
.
Teraz, aby odpowiedzieć na twoje pytanie. To, co liammclennan powiedział o używaniu Dir::[]
, jest poprawne - nie jest potrzebne finder
. Tak więc pytanie brzmi: jak pisać testy dla metod, które wywołują Dir::[]
? Masz trzy możliwości: 1) Użyj jednej z wyżej wymienionych bibliotek szyderczych i kodu pośredniczącego Dir::[]
(jest to prosta i łatwa metoda), 2) Zapisz pliki na dysku i sprawdź, czy są one przeczytane (ick), lub 3) Użyj biblioteki jak FakeFS, aby zapobiec IO dysku, ale nadal pozwala napisać naturalny wygląd testu.Poniższy przykład jest jeden możliwy sposób pisania/testowania to (używając RSpec i FakeFS), który jest nieco równolegle do pierwotnego projektu:
class CodeExtractor
def self.extract_dir(example_dir, target_dir)
Dir[example_dir + "/*.md"].each do |filename|
self.extract(filename, target_dir)
end
end
def self.extract(*args)
self.new(*args).extract
end
def extract(filename, target_dir)
# ...
end
end
# The spec...
require 'fakefs/spec_helpers'
describe CodeExtractor do
include FakeFS::SpecHelpers
describe '::extract_dir' do
it "extracts each markdown file in the provided example dir" do
FileUtils.touch(["foo.md", "bar.md"])
CodeExtractor.should_receive(:extract).with(Dir.pwd + "/foo.md","/target")
CodeExtractor.should_receive(:extract).with(Dir.pwd + "/bar.md","/target")
CodeExtractor.extract_dir(Dir.pwd, "/target")
end
end
describe '#extract' do
it "blah blah blah" do
# ...
end
end
end
oczywiście, nie jest to kwestia, czy taki test dodaje tyle wartość zasługuje na jego istnienie. Nie sądzę, że wpadnę na to .... Jeśli zdecydujesz się użyć FakeFS, pamiętaj, że stosy błędów mogą nie być pomocne, ponieważ FS jest fałszywe, gdy RSpec próbuje wyłączyć numer linii nieistniejący FS. :) Zbiegiem okoliczności, mam trochę kodu, który czyta i parsuje slajdy Markdown na github. The specs może służyć jako dalsze examples, jak możesz podejść do testowania takich rzeczy w Ruby. HTH, i powodzenia.
Przez "przepisanie tego w teście" masz na myśli łatanie małp? –