我有一个执行多个数据库操作的类,我想编写一个单元测试,用于验证这些操作是否都在事务中执行。有什么好干净的方法呢?
以下是一些示例代码,说明了我正在测试的类:
class StructureUpdater
def initialize(structure)
@structure = structure
end
def update_structure
SeAccount.transaction do
delete_existing_statistics
delete_existing_structure
add_campaigns
# ... etc
end
end
private
def delete_existing_statistics
# ...
end
def delete_existing_structure
# ...
end
def add_campaigns
# ...
end
end
答案 0 :(得分:0)
Rspec允许您声明数据在特定块的范围内已更改。
it "should delete existing statistics" do
lambda do
@structure_updater.update_structure
end.should change(SeAccount, :count).by(3)
end
...或某些此类取决于您的架构的外观等。不确定delete_existing_statistics究竟发生了什么,因此请相应地修改更改子句。
编辑:一开始我不明白这个问题,道歉。您可以尝试断言以确保以给定顺序发生这些调用(同样,使用RSpec):编辑:您无法在对该事务中 内的呼叫期望的测试中声明对某事务的期望。我能从袖口拿出最接近的是:
describe StructureUpdater do
before(:each) do
@structure_updater = StructureUpdater.new(Structure.new)
end
it "should update the model within a Transaction" do
SeAccount.should_receive(:transaction)
@structure_updater.update_structure
end
it "should do these other things" do
@structure_updater.should_receive(:delete_existing_statistics).ordered
@structure_updater.should_receive(:delete_existing_structure).ordered
@structure_updater.should_receive(:add_campaigns).ordered
@structure_updater.update_structure
end
end
一个更多尝试:另一个小问题是强制事务块中的一个后续方法调用引发,并断言数据库中没有任何变化。例如,假设Statistic是一个模型,而delete_existing_statistics将更改DB中统计信息的计数,您可以知道如果事务中稍后抛出的异常回滚了该更改,则会在事务中发生调用。类似的东西:
it "should happen in a transaction" do
@structure_updater.stub!(:add_campaigns).and_raise
lambda {@structure_updater.update_structure}.should_not change(Statistic, :count)
end