ruby - Spec testing EventMachine-based (Reactor) Code -


i'm trying out whole bdd approach , test amqp-based aspect of vanilla ruby application writing. after choosing minitest test framework balance of features , expressiveness opposed other aptly-named vegetable frameworks, set out write spec:

# file ./test/specs/services/my_service_spec.rb # requirements test running , configuration require "minitest/autorun" require "./test/specs/spec_helper" # external requires # minitest specs eventmachine require "em/minitest/spec" # internal requirements require "./services/distribution/my_service" # spec start describe "myservice", "a gateway amqp server" # connectivity "cannot connect unreachable amqp server" # line breaks execution, commented out # include em::minitest::spec # ... # (abridged) alter configuration specifying # invalid host such "l0c@alho$t" or such # ... # try connect , expect fail exception myapp::myservice.connect.must_raise eventmachine::connectionerror end end 

i have commented out inclusion of the em-minitest-spec gem's functionality should coerce spec run inside eventmachine reactor, if include run sketchier exception regarding (i suppose) inline classes , such: nomethoderror: undefined method 'include' #<#<class:0x3a1d480>:0x3b29e00>.

the code testing against, namely connect method within service based on article , looks this:

# main namespace module myapp # gateway amqp server class myservice # external requires require "eventmachine" require "amqp" # main entry method, connects amqp server def self.connect # add debugging, spawn thread thread.abort_on_exception = true begin @em_thread = thread.new { begin em.run @connection = amqp.connect(@settings["amqp-server"]) amqp.channel = amqp::channel.new(@connection) end rescue raise end } # fire thread @em_thread.join rescue exception raise end end # method connect end end # class myservice 

the whole "exception handling" merely attempt bubble exception out place can catch/handle it, didn't either, or without begin , raise bits still same result when running spec:

eventmachine::connectionerror: unable resolve server address, actually is expect, yet minitest doesn't play whole reactor concept , fails test on ground of exception.

the question remains: how 1 test eventmachine-related code using minitest's spec mechanisms? another question has been hovering around regarding cucumber, unanswered.

or should focus on main functionality (e.g. messaging , seeing if messages sent/received) , forget edge cases? insight help!

of course, can come down code wrote above, maybe it's not way 1 goes writing/testing these aspects. be!

notes on environment: ruby 1.9.3p194 (2012-04-20) [i386-mingw32] (yes, win32 :>), minitest 3.2.0, eventmachine (1.0.0.rc.4 x86-mingw32), amqp (0.9.7)

thanks in advance!

sorry if response pedantic, think you'll have easier time writing tests , library if distinguish between unit tests , acceptance tests.

bdd vs. tdd

be careful not confuse bdd tdd. while both quite useful, can lead problems when try test every edge case in acceptance test. example, bdd testing you're trying accomplish service, has more you're doing message queue connecting queue itself. happens when try connect non-existent message queue fits more realm of unit test in opinion. it's worth pointing out service shouldn't responsible testing message queue itself, since that's responsibility of amqp.

bdd

while i'm not sure service supposed exactly, imagine bdd tests should like:

  1. start service (can in separate thread in tests if need to)
  2. write queue
  3. wait service respond
  4. check results of service

in other words, bdd (or acceptance tests, or integration tests, want think them) can treat app black box supposed provide functionality (or behavior). tests keep focused on end goal, more meant ensuring 1 or 2 golden use cases, rather robustness of app. that, need break down unit tests.

tdd

when you're doing tdd, let tests guide in terms of code organization. it's difficult test method creates new thread , runs em inside thread, it's not hard unit test either of these individually. so, consider putting main thread code separate function can unit test separately. can stub out method when unit testing connect method. also, instead of testing happens when try connect bad server (which tests amqp), can test happens when amqp throws error (which code's responsibility handle). here, unit test can stub out response of amqp.connect throw exception.


Comments

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

c++ - Accessing inactive union member and undefined behavior? -

php - Get uncommon values from two or more arrays -