From: Dido Sevilla Date: 2006-05-12T06:57:33+09:00 Subject: Unit testing with mock objects I've been writing an extensive set of unit tests for a bunch of code that I've been developing over the past couple of years to improve its maintainability and have in the process needed to make more than a few mock objects to encapsulate functionality like databases, web services, distributed objects, and peripherals to which the program interfaces. I've been wondering what is the best way to refactor these kinds of classes so that it becomes easy to inject mock objects where these domain objects are required. What I've been doing so far is to attach a block to the initialize method that, when specified, is called to instantiate these mock objects, e.g.: class Foo def initialize(x, y, &block) if block_given? dobjs = block.call @domain_obj1 = dobjs[:domain_obj1] @domain_obj2 = dobjs[:domain_obj2] else @domain_obj1 = DomainObj1.new @domain_obj2 = DomainObj2.new end end so that in my testing code I can do the following: FlexMock.use("domain_obj1") do |dobj1| FlexMock.use("domain_obj2").do |dobj2| f = Foo.new(x, y) { {:domain_obj1 => dobj1, :domain_obj2 => dobj2 } } end end but this hardly feels like the "right" way to do it. It feels like such a kludge. I know I could write factory methods to create my domain objects and then reopen the class at testing time and rewrite the factory methods to return the mock objects, but then it's not exactly clear how I could feed these rewritten factory methods with mock objects instantiated as above, from within the test. I could rewrite the initialization method to accept instances of my domain objects instead so that at test time I could just feed it with my mock objects, but that would also require me to rewrite all the code that uses instances of the class in question as well, and that's not such a good idea to do everywhere. Any suggestions?