Какой хороший способ проверить в модульном тесте, что транзакция ActiveRecord используется? - PullRequest
1 голос
/ 14 декабря 2009

У меня есть класс, который выполняет несколько операций с базой данных, и я хочу написать модульный тест, который проверяет, что все эти операции выполняются в транзакции. Какой хороший чистый способ сделать это?

Вот пример кода, иллюстрирующего класс, который я тестирую:

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

1 Ответ

0 голосов
/ 14 декабря 2009

Rspec позволяет утверждать, что данные изменились в области действия конкретного блока.

it "should delete existing statistics" do
    lambda do
        @structure_updater.update_structure
    end.should change(SeAccount, :count).by(3)
end

... или что-то подобное, в зависимости от того, как выглядит ваша схема, и т. Д. Не уверен, что именно происходит в delete_existing_statistics, поэтому соответствующим образом измените предложение change.

РЕДАКТИРОВАТЬ: сначала не понял вопрос, мои извинения. Вы можете попробовать следующее, чтобы убедиться, что эти вызовы происходят в заданном порядке (опять же, с использованием 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

ONE MORE TRY: Еще один незначительный взлом - заставить один из более поздних вызовов метода в блоке транзакции поднять и утверждать, что в БД ничего не изменилось. Например, если предположить, что Statistic является моделью, а delete_existing_statistics изменит счетчик Statistication в БД, вы можете знать, что вызов произошел в транзакции, если позднее в транзакции возникнет исключение, откатившее это изменение. Что-то вроде:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...