Skip to content

Instantly share code, notes, and snippets.

@lukeredpath
Created August 26, 2010 01:12
Show Gist options
  • Save lukeredpath/550604 to your computer and use it in GitHub Desktop.
Save lukeredpath/550604 to your computer and use it in GitHub Desktop.
require 'eventmachine'
require 'json'
require 'mimic'
require 'logger'
module FakeCampfireServer
class Handler
def initialize(ipc)
@ipc = ipc
@ipc.delegate = self
@port = 10001
end
def stub(path, headers, status, response)
puts "Mimicing #{path}."
Mimic.cleanup!
Mimic.mimic(:port => @port) do
get(path) do
[status, headers, response]
end
end
end
def configure(options)
@port = options[:port].to_i
end
end
class IPCServer < EventMachine::Connection
attr_accessor :delegate
def receive_data(data)
command = JSON.parse(data)
puts "Received #{command.inspect}"
if respond_to?(command['command'])
puts "➜ Dispatching #{command['command']}."
send(command['command'], command['options'])
else
puts "➜ Could not dispatch #{command['command']}"
send_json("error" => "Unknown command: #{command['command']}.")
end
end
def send_json(data)
send_data data.to_json
end
end
module IPCommands
def echo(options) # for testing the connection
send_json options
end
def configure(options)
self.delegate.configure(options)
end
def stub(options)
self.delegate.stub(options['path'], options['headers'] || {}, options['status'] || 200, options['response'])
send_json('command' => 'stub', 'status' => 'OK')
end
end
def self.start!(port = 8081)
IPCServer.send(:include, IPCommands)
EventMachine.run do
puts "Listening on port #{port}..."
EventMachine.start_server('127.0.0.1', port, IPCServer) do |server|
$handler = Handler.new(server)
end
end
end
end
//
// RubyIPCTest.m
// Firelight
//
// Created by Luke Redpath on 26/08/2010.
// Copyright 2010 LJR Software Limited. All rights reserved.
//
#import "AssertEventually.h"
#import "TestHelper.h"
#import "RubyIPC.h"
#import "LRResty.h"
SPEC_BEGIN(RubyIPCSpec)
describe(@"Ruby Inter-Process communication", ^{
it(@"should respond to echo commands", ^{
__block id receivedResponse = nil;
[RubyIPC connectTo:@"localhost" onPort:8081 onConnect:^(RubyIPC *ipc) {
[ipc sendCommand:@"echo" withOptions:[NSDictionary dictionaryWithObject:@"hello world how are you" forKey:@"message"] callback:^(NSDictionary *response){
receivedResponse = [response retain];
}];
}];
assertEventuallyThat(&receivedResponse, hasEntry(@"message", @"hello world how are you"));
});
});
SPEC_END
SPEC_BEGIN(RemoteMimicTest)
describe(@"RemoteMimic", ^{
beforeAll(^{
[RemoteMimic setRemoteHost:@"localhost"];
[RemoteMimic setRemotePort:8081];
});
it(@"should be able to mimic a HTTP service and return a canned response", ^{
__block id receivedResponse = nil;
[[RemoteMimic onPort:9099] path:@"/test" returns:@"fake response" whenReady:^{
[[LRResty client] get:@"http://localhost:9099/test" withBlock:^(LRRestyResponse *response) {
receivedResponse = [response retain];
}];
}];
assertEventuallyThat(&receivedResponse, is(notNilValue()));
assertThat([receivedResponse asString], equalTo(@"fake response"));
});
});
SPEC_END
@lukeredpath
Copy link
Author

So, the gist is...Ruby + Mimic is a great way of stubbing out web services for end to end testing, and not just for Ruby apps, but anything really (in this case, I want to test iPhone/iPad apps). The thing is...writing a huge Ruby script that stubs out loads of endpoints means your test stubs end up being separated from the test cases (written in Objective C) that use them. Tests disconnected from their fixtures == FAIL.

So...this lets me use Mimic generically, telling it what to serve up and for what path, directly from within my Objective-C test case, all asynchronous and everything.

Easy huh?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment