我使用hanami
框架和rspec
lib来测试我的代码和PG数据库。当我尝试测试一个动作时,我得到以下错误:
PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block
我的操作已包含在存储库事务中:
def call(params, dependencies)
begin
dependencies.repository.transaction do
create_user(params, dependencies)
assign_tags(params, dependencies)
assign_notes(params, dependencies)
end
rescue Hanami::Model::Error, Domain::Errors::Exception => error
raise Domain::Errors::CreateUserFailed, error.message
end
end
在这里你可以看到我的部分测试失败了:
it 'should raise exception if params contains duplicated email' do
expect{service.call(duplicated_email)}
.to raise_exception(Domain::Errors::CreateUserFailed)
.with_message('Duplicated values found (id or
email)')
end
it 'should raise exception if params contains duplicated note id' do
expect{service.call(duplicated_note_id)}
.to raise_exception(Domain::Errors::CreateUserFailed)
end
第一次测试通过,但第二次测试通过了前面提到的异常。我知道这是因为先前的测试在事务块中引发了异常。我找到了这个answer中提到的解决方案,但我不适用于我的情况。
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with :deletion
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
感谢所有答案:)
编辑:
Failure/Error:
expect{service.call(duplicated_note_id)}
.to raise_exception(Domain::Errors::CreateUserFailed)
.with_message('Duplicated values found in user notes (id)')
expected Domain::Errors::CreateUserFailed with "Duplicated values found in user notes (id)", got #<Domain::Errors::CreateUserFailed: PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block
> with backtrace:
# ./lib/domain/commands/create_user.rb:17:in `rescue in call'
# ./lib/domain/commands/create_user.rb:8:in `call'
# ./spec/domain/commands/create_user_spec.rb:210:in `block (3 levels) in <top (required)>'
# ./spec/domain/commands/create_user_spec.rb:210:in `block (2 levels) in <top (required)>'
# ./spec/domain/commands/create_user_spec.rb:210:in `block (2 levels) in <top (required)>'