在Java等强类型语言中,由于返回类型与方法签名不匹配,因此代码无法编译,因此无需显式检查返回的对象的类型。例如当期望整数时,您不能返回布尔值。
在松散类型的语言(如Ruby,JavaScript,Python等)中,可以返回任何内容。编写检查方法返回的对象类型的单元测试是否有意义?我认为,这将确保在期望布尔值的地方返回布尔值。
是否甚至有必要在下面进行单元测试?
============================
尝试Ruby示例:
first_module.rb:
module FirstModule
TypeA = Struct.new(
:prop1,
:prop2)
self.create_type_a
TypeA.new(
'prop1Val',
'prop2Val')
end
end
type_a_repository.rb:
module TypeARepository
def self.function_to_test
FirstModule.create_type_a # This will return TypeA object
end
end
type_a_repository_spec.rb:
RSpec.describe '' do
describe '' do
before do
allow(FirstModule).to receive(:create_type_a)
.and_return(FirstModule.create_type_a)
end
it '' do
result = TypeARepository.function_to_test
expect(result).to be_a(FirstModule::TypeA) # is this necessary?
end
end
end
答案 0 :(得分:6)
如果您使用programming by contract,那么答案通常是“否”,只要返回值符合预期的标准(通常是很松散的),您就不会抱怨。
例如:
# Adds together zero or more integer values and returns the sum
def sum(*numbers)
numbers.inject(0,:+)
end
在测试时,您将执行以下操作:
assert_equal 0, sum
assert_equal 1, sum(1)
assert_equal 0, sum(1, -1)
现在提供非整数值会怎样?
sum('1')
# => Exception: String can't be coerced into Integer
原始合同未将其指定为有效用例,因此有例外情况是必要的。如果要扩展范围:
# Adds together zero or more numerical values and returns the sum
def sum(*numbers)
numbers.map(&:to_i).inject(0,:+)
end
现在您可以将非整数值加在一起:
assert_equal 6, sum(1, 2.0, '3')
请注意,只要结果通过了断言测试,您就会一直满意。在Ruby 6.0
,6
和"6"
中,它们都是不同的,不相等的,因此不必担心输入错误的类型。
在其他语言中可能并非如此,因此您可能需要更具体地了解结果。重要的是,如果可以的话,请避免进行文字测试,而应按预期使用结果 。例如:
assert_equal "this is amazing", "this is " + amazing_string_result
只要amazing_string_result
中出现的任何内容都可以附加到字符串上,并且结果匹配,这是可接受的响应。
当您希望使用文字true
或false
而不是像1
这样的 truthful 值时,这通常会起作用:
assert_true some_method?(:value)
如果返回的是真实但非文字型true
值,则合约被破坏并且失败。
请记住,您可以拥有无限数量的偏执狂。您确定自己的值正确累加了吗?
assert_equal 6, 1 + 2 + 3
assert_equal 6, 6
assert_equal 6, '6'.to_i
assert_true true
在某些时候,您不再测试代码,而是在执行该代码的编程语言或硬件上运行回归测试,如果您为您的代码。
最佳单元测试: