Try this:

class RSpecLogger
  def errors
    @errors ||= []
  end

  def error(e)
    errors << e
  endend
RSpec.configure do |c|
  c.before do
    @rspec_logger = RSpecLogger.new
  end

  c.after do
    expect(@rspec_logger.errors).to be_empty,
      "Got some logged errors:
#{@rspec_logger.errors.map(&:message).join("\n")}"
  endend

​

On Wed, Nov 25, 2015 at 8:13 AM, Tim Mertens <[email protected]> wrote:

> Happy Thanksgiving!
>
> I am testing an application that reports all errors through a common
> interface, which then distributes errors to various loggers (rails logs,
> logentries, etc).  Each reporter logs messages based on severity and
> environment.  In our test environment, the generic logging interface is set
> to always re-raise reported errors such that tests will always fail if an
> error is reported through this interface that is not expected.  In the
> majority of cases, this means that conditions where such errors would
> normally be reported, handled and swallowed in production will instead
> re-raise the exception (in test) and ultimately cause the test to fail if
> the error is not explicitly expected.
>
> However, we still observe conditions where:
>
>    1. class A calls class B calls class C.
>    2. class C raises an exception.
>    3. class B catches said exception and logs it via the Logger.
>    4. The Logger re-raises the error.
>    5. class A catches the re-raised error but swallows it completely.
>    6. The test passes if there are no failing expectations as a result,
>    even though an exception occurred.
>
> Is there some way to report errors to rspec via a sideband messaging
> channel, such that we can implement a logger that would simply report
> errors directly to rspec and bypass the need for an exception to bubble all
> the way up to the top of the stack in order for a test to fail?
>
> The only possible solution I know of so far would be to set a global
> expectation for the logging class not to receive an error message, and
> override that behavior in individual tests; however, this feels like the
> wrong solution and I'm not sure it would actually work as desired to modify
> the expectation behavior from `expect().not_to receive` (in a global before
> hook) to `allow().to receive`, or `expect().to receive`.  Or we would have
> to override the default expectation via metadata in individual tests which
> again is not an ideal solution.
>
> Here is a rudimentary example of the problem:
>
> class RSpecLogger
>   def error(e)
>     # somehow report sideband error to rspec
>   end
> end
>
> class SomeOtherReporter
>   def error(e)
>     puts e.message
>   end
> end
>
> class MyErrorLogger
>   LOGGERS = [
>     SomeOtherReporter.new,
>     RSpecLogger.new
>   ]
>
>   def self.error(exception)
>     LOGGERS.each { |r| r.error(exception) }
>
>     raise exception if should_reraise? # This could be replaced entirely
> via sideband reporting
>   end
>
>   def self.should_reraise?
>     true # if in test environment
>   end
> end
>
> describe MyErrorLogger do
>   it 'should fail even if reraise is caught elsewhere' do
>     begin
>       begin
>         # Something raises an exception
>         raise StandardError.new("Foo message")
>       rescue => e
>         # We rescue and log it
>         described_class.error(e)
>       end
>     rescue => e
>       # the reraised error is swallowed somewhere further up the stack, so
> the test passes if no assertions fail.
>       nil
>     end
>   end
> end
>
> Thanks,
> Tim
>
> --
> You received this message because you are subscribed to the Google Groups
> "rspec" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/rspec/d0fcb0da-8578-49f0-be1e-9a9094276fe0%40googlegroups.com
> <https://groups.google.com/d/msgid/rspec/d0fcb0da-8578-49f0-be1e-9a9094276fe0%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/CADUxQmsrCoH2QYjYqr0tNu7d2tZgqS1yBpC54WnTWqcVWAY1hw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to