Thoughts on Software by Andrew Davey
| | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|
| 24 | 25 | 26 | 27 | 28 | 29 | 30 | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | 29 | 30 | 31 | 1 | 2 | 3 | 4 |
Search
Navigation
Categories
Blogroll
|

Wednesday, July 04, 2007
Better Syntax for Mocking
I thought some more about the syntax of my Rhino Mock DSL. It can feel unnatural putting all the mock expectation code before the call to the object being tested. I came up with this working prototype instead:
[Test]
def Get_data_objects_for_nonexistent_company_throws():
with_mocks:
database = mocks.CreateMock[of IDatabase]()
userProvider = StubUserProvider("andrew", "bad corp")
userProvider.MakeCurrent()
execute:
uds = UserDataService(database, userProvider)
expect_throw FaultException[of GetDataObjectsFault]:
uds.GetDataObjects()
assert thrown_exception.Detail.Type.Equals(GetDataObjectsFaultType.InvalidCompany)
assuming:
database.GetUserID("andrew", "bad corp")
returned 1
assuming:
database.GetCompanyID("bad corp")
returned 0 # returning 0 from database implies nonexistent company.
The with_mocks method sets up the mock repository and a Store object. The execute and assumption methods then put their blocks into the Store. At the end of with_mocks I iterate through assumptions calling each to set up the Rhino Mock expectations. Following that is: mocks.ReplayAll(), call to the "execute" block, then mocks.VerifyAll().
The other clever bit in there is the expect_throw method. This runs the block inside a try...except and fails if no exception (or wrong exception type) is thrown. It puts the exception object into field that is readable using thrown_exception. This means we can then test assertions about the exception contents. I had to cheat a bit and declare thrown_exception as "duck" in Boo i.e. it is late bound. This is so we can access members on the actual object despite not really knowing about it at compile time.
I like the readability now. The outline is:
- Initialize mocks and data objects
- Call the object being tested
- Assert about the result
- State the assumptions about how dependencies are used
The key bit, I feel, is that the call to the object being tested is not buried down at the bottom of the method.
How does everyone else feel about this modified approach?
Wednesday, July 04, 2007 10:41:55 AM (GMT Standard Time, UTC+00:00)
.net | boo | dsl | mock_objects | programming | rhino_mocks

Tuesday, July 03, 2007
Microsoft and External .NET Languages
Why can't Microsoft do more to support external projects like Boo and Nemerle? It drives me insane seeing all the love Python and Ruby are getting from Microsoft, when there are languages out there that embraced the CLR from day one being ignored!
To be honest, by "love" I mean IDE love. Nemerle is a great language - light years ahead of C#. The same goes for Boo. But the tool support for these languages in poor. The Nemerle VSIP project barely usable for any serious work and for Boo the only real option is SharpDevelop.
I confess, I am a total Visual Studio junkie. I need my tools. Using emacs and cmd prompt for some project with hundreds of source, resource and data files is stupid. You shall take intellisense from my cold dead hands!
The problem it seems that developing a reliable, complete, VS integration package is very hard. Microsoft: please reach out to these pioneering developers and offer them what ever they need to get their awesome languages in Visual Studio. Just do it. In fact, go one better and release Boo Express and Nemerle Express for free! The .NET world will thank you.
Reading this kind of shit makes me so very sad.
Tuesday, July 03, 2007 8:40:46 AM (GMT Standard Time, UTC+00:00)

Monday, July 02, 2007
Rhino Mocks DSL in Boo
I recently learnt that Boo now supports a DSL-friendly syntax. A while back I created (and almost finished!) a set of syntactic macros in Boo to make using Rhino Mocks much more natural. Creating macros can be hard work though and gets pretty hacky in places.
The new DSL-friendly syntax in Boo means I can achieve 80% of the same easy-reading code, but using only methods and blocks!
In about 10 minutes I whipped up this:
namespace ConsoleDemo
import System
import Rhino.Mocks
import Rhino.Mocks.BooDsl.MockDsl
interface IModel:
def CalculateScore(input as int) as int
interface IView:
def DisplayScore(score as int)
interface IPresenter:
def Init()
class Presenter(IPresenter):
_model as IModel
_view as IView
def constructor(model as IModel, view as IView):
_model = model
_view = view
def Init():
score = _model.CalculateScore(0)
_view.DisplayScore(score)
def Test_presenter_init():
with_mocks:
// Create mocks of the dependencies
model = Mocks.CreateMock of IModel()
view = Mocks.CreateMock of IView()
// Create the object we are testing
presenter = Presenter(model, view)
// Record what we expect the presenter to
// do with its dependencies.
record:
expect:
model.CalculateScore(0)
// Set the return value for the
// previous mock call.
mock_return 42
expect:
view.DisplayScore(42)
// Now tell the presenter to do its stuff,
// so we can verify it behaves correctly.
verify:
presenter.Init()
print "testing..."
Test_presenter_init()
print "all good!"
print "Press any key to continue . . . "
Console.ReadKey(true)
The import of "Rhino.Mocks.BooDsl.MockDsl" brings some new methods into scope. with_mocks initializes a MockRepository. "Mocks" is actually a property referencing that repository, so we can call CreateMock, etc, on it. The record and verify methods make use of the Mocks.Record() and Mocks.Playback() methods. I prefer using "verify" to "playback". The "expect" method runs the code in its block, usually that invokes some mock method. It then calls "LastCall.Repeat.Once()" to set up the expectation. The "mock_return" method calls "LastCall.Return(value)" to set up the return value for the last mock call.
This is all a bit messy for now I know. I have just being throwing code down into this prototype to get a feel for what is possible. I reckon this could be really useful for people using Rhino Mocks.
If you like what you've seen or have any ideas let me know.
The DSL methods are as follows:
I am aware of more than one glaring danger in the code(!) but it does show what can be done.
namespace Rhino.Mocks.BooDsl
import System
import Rhino.Mocks
callable Block()
static class MockDsl:
private static _instance as MockDslImpl
static def with_mocks(b as Block):
_instance = MockDslImpl()
b()
_instance = null
static def record(b as Block):
assert _instance != null
_instance.Record(b)
static def verify(b as Block):
assert _instance != null
_instance.Verify(b)
static def expect(b as Block):
assert _instance != null
_instance.Expect(b)
static def mock_return(value as object):
assert _instance != null
_instance.MockReturn(value)
static Mocks as MockRepository:
get:
assert _instance != null
return _instance.Mocks
private class MockDslImpl:
mocks as MockRepository
def constructor():
mocks = MockRepository()
public Mocks as MockRepository:
get:
return mocks
public def Record(b as Block):
using mocks.Record():
b()
public def Verify(b as Block):
using mocks.Playback():
b()
public def Expect(b as Block):
b()
LastCall.Repeat.Once()
public def MockReturn(value as object):
LastCall.Return(value)
Monday, July 02, 2007 11:03:52 PM (GMT Standard Time, UTC+00:00)
.net | boo | dsl | mock_objects | programming | rhino_mocks

Wednesday, June 27, 2007
Degree Result Day
I got my University of Warwick Computer Science BSc result today: First Class!
Whilst this has no affect on my plan to start my own business, it's still nice to know that I'm not that awful at computer science. :)
Right then, on with the code monkeying for now.
Wednesday, June 27, 2007 10:29:54 PM (GMT Standard Time, UTC+00:00)
degree | university

Monday, June 18, 2007
Model-view-presenter in Silverlight
Using Silverlight 1.1 means I am able to write .NET code that runs in the web browser. This should make it very easy to implement a clean model-view-presenter (MVP) architecture. I am envisaging a model that acts as a web-service proxy to get data and perform actions on the server. The view would thinly wrap the XAML UI. The presenter would handle all the interactions between the other two. This makes for very unit-testable code.
The one thing I'm not sure about is what level of granularity to use regards presenters and views. In XAML it is possible to define amazing interfaces that have animations and transitions between states. Should these different UI states have distinct view/presenter objects? Would it make sense to have a single XAML canvas that implements a number of different View (OOP) interfaces?
Does anyone have good resources dealing with switching views?
Monday, June 18, 2007 3:04:07 PM (GMT Standard Time, UTC+00:00)

Sunday, June 10, 2007
Where now?
With exams completed, I am effectively done with university. I still have to wait for my results and attend graduation, but I am now free to do what ever I like!
It seems like everyone in my year is either staying on for more academia or seeking regular employment. Neither of these particularly appeals to me. The way I see it, I can innovate and invent out in the real world. I have really had enough of formal education. Of course I would not trade my time at university for anything. I have met some amazing people along the way and had some crazy adventures. I don't plan on slowing down however!
The default option then is to get a "real" job. This default sucks, in my opinion. I've felt this way for quite a few years, but it was always due to thinking I'd make more money working for myself. Recently I have noticed a change in my outlook. Whilst making enough money to be secure and enjoy life is important for me, being stinking rich seems less so.
I want to make a difference. Most software sucks. Let's fix this.
I need to do lots more research of course, in fact I reckon that part will never end. The human factors of software are becoming more prevalent every day. We are in possession of powerful new tools with which to craft future software. But it is so easy for us geeks to become distracted by the bells and whistles of some new technology. We need to think carefully about to leverage all our tools to best help our users.
I want this blog to be a mix of hardcore geekery and more subtle discussion about making software better. If I ever get too "head in the clouds" however please do call me out! I'm just one voice after all.
So what is the plan?! Stick the formula of "Coffee => Code => Cash" (i.e. consultancy) to pay the bills and develop real products (new and existing). Over the summer a new version of Insight for primary schools will get created, hopefully with sexy new graphics! Facebook presents a new and interesting platform that also requires attention. As for technology, Silverlight and .NET 3.5 will be regular themes here.
Sunday, June 10, 2007 9:25:32 PM (GMT Standard Time, UTC+00:00)
thinking

Sunday, June 03, 2007
Welcome to the New Blog
Hello and welcome to the new blog by me (Andrew Davey).
I will soon be graduating from the University of Warwick. So my blog hosted there will soon be discontinued. I fancied starting a new one that I have full control over, rather than pay them to maintain it. I will try to extract all the old entries and archive them somewhere soon.
I plan to blog at lot actively once university is out the way. Topics will include .NET, Silverlight, Nemerle and anything else new, cool and interesting in the software world!
Watch this space...
Sunday, June 03, 2007 11:42:33 AM (GMT Standard Time, UTC+00:00)
welcome