Dav*_*pak 9 .net c# ruby testing tdd
我一直在努力使我的标准方法适应测试驱动.NET代码到Ruby.
作为一个例子,我正在写一个类:
grab all *.markdown files from a directory
foreach file:
extract code samples from file
save code to file.cs in output directory
Run Code Online (Sandbox Code Playgroud)
通常对于.NET,我最终会得到类似的东西:
class ExamplesToCode {
public ExamplesToCode(IFileFinder finder, IExampleToCodeConverter converter) { ... }
public void Convert(string exampleDir, string targetDir) { ... }
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中(首先写的),我是模拟查找器和转换器.然后,我踩灭了finder.FindFiles("*.markdown")回说["file1", "file2"],检查converter.Convert("file1", targetDir)和converter.Convert("file2", targetDir)被调用.
我努力将这个应用于Ruby的地方是Ruby倾向于使用块和内部迭代器(例如array.each { |x| puts x }),并且包括模块而不是构造函数注入.我不确定如何在这些情况下对代码进行单元测试(没有设置完整的集成测试),而且.NET方法看起来非常不完美; 它似乎与Ruby自然运作的方式作斗争.
有关如何以Ruby方式执行此操作的任何建议?这个例子的Ruby测试的例子很棒.
你可以进行一个非常简单的测试,如下所示:
class ExamplesToCodeTest < Test::Unit::TestCase
def test_convert
# have some example markdown files in a fixtures directory
ExamplesToCode.convert("test/fixtures/*.markdown")
assert_equal expected_output_1, File.read("test/output/file_1.cs")
assert_equal expected_output_2, File.read("test/output/file_2.cs")
assert_equal expected_output_3, File.read("test/output/file_3.cs")
end
private
def expected_output_1
"... expected stuff here ..."
end
def expected_output_2
"... expected stuff here ..."
end
def expected_output_3
"... expected stuff here ..."
end
end
Run Code Online (Sandbox Code Playgroud)
我想这将是一个不错的集成测试,但这不是我真正喜欢的,我喜欢将我的代码分成小块
首先,我创建一个可以处理解析 markdown 文件的类,例如:
class MarkdownReaderTest < Test::Unit::TestCase
def test_read_code_sample_1
reader = MarkdownReader.new
code_sample = reader.read("fixtures/code_sample_1.markdown")
# or maybe something like this:
# code_sample = reader.parse(File.read("fixtures/code_sample_1.markdown"))
# if you want the reader to just be a parser...
assert_equal code_sample_1, code_sample
end
# ... repeat for other types of code samples ...
private
def code_sample_1
"text of code sample 1 here..."
end
end
Run Code Online (Sandbox Code Playgroud)
现在读取和解析 Markdown 文件的所有代码都在 MarkdownReader 类中。现在,如果我们不想实际编写文件,您可以使用 RR 或 Mocha 或其他东西进行一些模拟(我在这里使用 rr ):
class CodeSampleWriter < Test::Unit::TestCase
include RR::Adapters::TestUnit
def test_write_code_sample
# assuming CodeSampleWriter class is using the File.write()...
any_instance_of(File) do |f|
mock(f).write(code_sample_text) { true }
end
writer = CodeSampleWriter.new
writer.write(code_sample_text)
end
private
def code_sample_text
"... code sample text here ..."
end
end
Run Code Online (Sandbox Code Playgroud)
现在假设 ExamplesToCode 类使用 MarkdownReader 和 CodeSampleWriter 类,您可以再次将模拟对象与 RR 一起使用,如下所示:
class ExamplesToCodeTest < Test::Unit::TestCase
include RR::Adapters::TestUnit
def test_convert
# mock the dir, so we don't have to have an actual dir with files...
mock(Dir).glob("*.markdown") { markdown_file_paths }
# mock the reader, so we don't actually read files...
any_instance_of(MarkdownReader) do |reader|
mock(reader).read("file1.markdown") { code_sample_1 }
mock(reader).read("file2.markdown") { code_sample_1 }
mock(reader).read("file3.markdown") { code_sample_1 }
end
# mock the writer, so we don't actually write files...
any_instance_of(CodeSampleWriter) do |writer|
mock(writer).write_code_sample(code_sample_1) { true }
mock(writer).write_code_sample(code_sample_2) { true }
mock(writer).write_code_sample(code_sample_3) { true }
end
# now that the mocks are mocked, it's go time!
ExamplesToCode.new.convert("*.markdown")
end
private
def markdown_file_paths
["file1.markdown", "file2.markdown", "file3.markdown"]
end
def code_sample_1; "... contents of file 1 ..."; end
def code_sample_2; "... contents of file 2 ..."; end
def code_sample_3; "... contents of file 3 ..."; end
end
Run Code Online (Sandbox Code Playgroud)
希望这能让您了解如何在 Ruby 中进行测试。不是煽动性的,但在大多数情况下,依赖注入并不是在 Ruby 世界中看到或使用的——它通常会增加很多开销。模拟/双打通常是更好的测试选择。
| 归档时间: |
|
| 查看次数: |
430 次 |
| 最近记录: |