这是一个最佳实践问题。有明显的方法可以做到这一点,它们都没有恰到好处。
我经常需要测试是否会生成一些多行字符串。这通常会打破缩进,使一切看起来像一团糟:
class TestHelloWorld < Test::Unit::TestCase
def test_hello
assert_equal <<EOS, hello_world
Hello, world!
World greets you
EOS
end
end
使用<<-
我可以在这里缩进doc标记,但它不会删除heredoc中的缩进,它看起来仍然很糟糕。
class TestHelloWorld < Test::Unit::TestCase
def test_hello
assert_equal <<-EOS, hello_world
Hello, world!
World greets you
EOS
end
end
这让我可以缩进,但测试线的可读性会受到影响。这个gsub
真的感觉不对。
class TestHelloWorld < Test::Unit::TestCase
def test_hello
assert_equal <<-EOS.gsub(/^ {6}/, ""), hello_world
Hello, world!
World greets you
EOS
end
end
有没有办法测试那些真正可读的多行字符串?
答案 0 :(得分:9)
如果您正在构建Rails应用程序,请尝试使用strip_heredoc
,否则您可能始终需要active_support核心扩展。
您的示例可能如下所示:
require 'active_support/core_ext'
class TestHelloWorld < Test::Unit::TestCase
def test_hello
assert_equal <<-EOS.strip_heredoc, hello_world
Hello, world!
World greets you
EOS
end
end
如果您确实不想包含它们,则会从active_support复制以下代码,以及如何处理格式化的示例。
class String
def try(*a, &b)
if a.empty? && block_given?
yield self
else
__send__(*a, &b)
end
end
def strip_heredoc
indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
gsub(/^[ \t]{#{indent}}/, '')
end
end
答案 1 :(得分:7)
就我个人而言,我认为Ruby的缩进heredocs是无用的,它们应该更像Bash缩进的heredocs,并且还在字符串中删除空格...
无论如何,有几个图书馆试图处理这种情况。有很多库试图解决这个问题:
答案 2 :(得分:0)
我不确定其中任何一种都可称为“最佳实践”,但这里有四种可能性
class Hello
def self.world
"Hello, world!
World greets you
"
end
end
require 'test/unit'
class TestHelloWorld < Test::Unit::TestCase
#Define a constant array of multiline strings and test against the array
# see test_hello_4
# Alternatively store the multi-line strings in a Yaml fixture file and load
# them into a constant Hash or Array within a setup method
MLINE = [
"Hello, world!
World greets you
",
"Another multi line string",
]
# Create a method to return the string
def test_hello_1
assert_equal Hello.world, hello_world_string()
end
# Create the string using embedded newlines
def test_hello_2
assert_equal Hello.world, "Hello, world!\n World greets you\n"
end
# if you only have 1 in the test then put it in a DATA section
def test_hello_3
assert_equal Hello.world, DATA.read
end
def test_hello_4
assert_equal Hello.world, MLINE[0]
end
def hello_world_string
"Hello, world!
World greets you
"
end
end
__END__
Hello, world!
World greets you
全部通过
Loaded suite test_hello_world
Started
....
Finished in 0.00083 seconds.
4 tests, 4 assertions, 0 failures, 0 errors
我个人更喜欢带嵌入换行符的字符串(方法2),除非字符串很长,在这种情况下我会使用DATA部分。
答案 3 :(得分:0)
是关于格式化还是关于内容的测试?
如果它是关于格式化的测试,也许你的测试水平太高了,你应该测试一个“Formatter”类,你可能会找到一种方法来测试类,使得多行文本比较无用。然后,您将能够模拟Formatter类以检查它是否将接收所需的所有内容。例如,Formatter可以是一个具有 add_line 方法的类,该方法在给出每个参数后添加“\ n”,并返回将返回多行字符串的 formatted_string 。一旦你测试了Formatter类,你就必须检查它是否被正确调用。这样,您就可以将内容测试与格式测试分开。
如果是对内容的测试,也许您应该按行分割hello_world,然后检查第一行是否包含“Hello,world”,第二行包含“World greets you”。
我认为测试整个多行文本块并不是一个好习惯。