我的应用程序的核心是一个引擎,它采用问题规范,编码为数据结构,并生成我们需要的结果。有两种方法可以实例化规范数据结构:通过解析脚本或通过Rails UI。在Rails的情况下,数据结构是DB中的模型对象,在脚本情况下,它是模型类的内存中实例。引擎位于一个单独的gem中,因此脚本驱动的进程可以独立运行而无需Rails。
我的问题是如何确保两个数据结构,即Rails DB模型和内存模型,实现相同的合同。如果这是Java,我会写一个两个模型类都会实现的接口,但在Ruby中我依赖于duck-typing。我将为每个模型进行测试,但只有一个测试套件会更加干燥。但是,我无法看到如何在gem项目和rails项目之间共享测试。
关键的挑战是:假设我对Rails模型添加了一个责任,我如何保证相应的责任被添加到脚本内存模型中,反之亦然?
答案 0 :(得分:1)
我想你应该创建一个模块,负责检查接收器类是否包含所需的方法。
这样的事情:
module Contract
STATIC_METHODS = [ :class_foo ]
INSTANCE_METHODS = [ :instance_foo ]
def self.included(receiver)
STATIC_METHODS.each do |method|
raise("missing class method #{method}") unless receiver.respond_to? method
end
INSTANCE_METHODS.each do |method|
raise("missing instance method #{method}") unless receiver.instance_methods.include? method.to_s
end
end
end
class YourClass
def self.class_foo
end
def instance_foo
end
include Contract
end
请注意在文件末尾包含Contract
否则,它将在逻辑上失败(不会定义方法)。
关于您的测试,您应该创建一些常见测试并在类中运行它们,例如:it_should_behave_like