Forum: RSpec DB transactions w/ RSpec

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Francis H. (Guest)
on 2009-05-06 00:31
(Received via mailing list)
Sorry if this has been answered elsewhere, Google was not very helpful
to me on this one. If I'm running a model spec and am one of those
benighted souls who wants to hit the DB while doing so, is there a way
for me to tell RSpec to skip transactions? In Test::Unit I can say
"uses_transaction :test_should_do_something", but am not sure what the
analogous thing would be in RSpec.

Thanks in advance,
Francis
Nicholas Van W. (Guest)
on 2009-05-06 18:00
(Received via mailing list)
As far as I can tell, RSpec simply uses inherited TestCase capabilities
for
transactions, including use_transactional_fixtures (it's config setting
is
simply passed on) and likely uses_transaction.

I'm guessing you can do something like:

    uses_transaction :create
    it "should save message" do
        ...
    end

At least it gives no exception for me.

The TestCase logic is pretty simple- it skips transactional fixtures if
the
method is in it's array, so I imagine it works.

If not, this shoulda ticket talks about the same need, with a patch that
integrates it into shoulda contexts. That might give some clues.
https://thoughtbot.lighthouseapp.com/projects/5807...

BTW- I happened to be watching your RubyConf2008 Testing Heresies talk
yesterday. Good talk.

Regards,
Nick
Francis H. (Guest)
on 2009-05-06 20:45
(Received via mailing list)
On Wed, May 6, 2009 at 9:47 AM, Nicholas Van W.
<removed_email_address@domain.invalid> wrote:
> At least it gives no exception for me.
> The TestCase logic is pretty simple- it skips transactional fixtures if the
> method is in it's array, so I imagine it works.
> If not, this shoulda ticket talks about the same need, with a patch that
> integrates it into shoulda contexts. That might give some clues.
> https://thoughtbot.lighthouseapp.com/projects/5807...

Any thoughts on what uses_transaction wants as an argument? I can't
help but feel like I've tried 10 combinations of ways to do this, and
there's some 11th way that will be easy but I haven't thought to try.

For context, my code doesn't even use transactions; it's using a 2nd
DB connection to a slave DB, which will be different in some envs and
not others. This seems to get tripped up by transactions since the
master connection makes a change to the DB and the slave connection
needs to see it right away. (Yes I know in production there are
latency issues, that's acceptable in this case.)

> BTW- I happened to be watching your RubyConf2008 Testing Heresies talk
> yesterday. Good talk.

Thanks!

Francis
Nicholas Van W. (Guest)
on 2009-05-06 23:15
(Received via mailing list)
The rails code is pretty straightforward:  def
uses_transaction(*methods)
        @uses_transaction = [] unless defined?(@uses_transaction)
        @uses_transaction.concat methods.map(&:to_s)
      end

      def uses_transaction?(method)
        @uses_transaction = [] unless defined?(@uses_transaction)
        @uses_transaction.include?(method.to_s)
      end
    end

    def run_in_transaction?
      use_transactional_fixtures &&
        !self.class.uses_transaction?(method_name)
    end

Works for me in my tests.

uses_transaction "it should do this"
it "should do this" do
  puts "runs in transaction=#{self.run_in_transaction?}"
end

runs as expected, providing false when the uses_transaction is set, and
true
otherwise (assuming   config.use_transactional_fixtures = true).

Regards,
Nick
Francis H. (Guest)
on 2009-05-07 00:06
(Received via mailing list)
Yeah, that worked for me, thanks. And for whatever reason nesting was
part of the problem, but if I put it all in one top-level describe
with the examples below it worked fine.

FH


On Wed, May 6, 2009 at 2:42 PM, Nicholas Van W.
This topic is locked and can not be replied to.