I started experimenting with Mono this week. The reason is simple enough: somebody wants me to write a small application that will run on their Windows box. The problem is, I own a Mac and a Linux powered laptop (yes, taking the Vista sticker off was a exercise in patience that left a lot of residual glue on the laptop...) Mono is a perfect solution for writing .Net software on Linux that will run on Windows.
The Setup
I run OpenSuse 11.1 because I figured I might as well go with the distribution that was created by the people who are currently behind Mono: Novell. Also, at the time of this writing, I have Mono 2.4, which is .Net 3.5 compatible, and Monodevelop 2.0 installed. As a bonus, I realized today that NUnit was also installed: version 2.4.8.
The Solution
Creating a new solution with Monodevelop is pretty straightforward.

As you can see, it's fairly similar to the Visual Studio experience. I selected the Library type of project and named it MyTest. After clicking the Forward button, Monodevelop asked me if I wanted to add packaging, unix integration or other little nifties to my project. I graciously declined.

The above image depicts what you get when you create a new, empty library project. Eager to get on my way, I coded one of the simplest class I've ever coded:
1:
2: using System;
3:
4: namespace MyTest
5: {
7: public class MyClass
8: {
9: public string MyString { get; set; }
10: public MyClass()
11: {
12: }
13: }
14: }
And I then set out to write a test using Scott Bellware's SpecUnit. First, I added a NUnit library project to my solution, which I called MyTest_spec.

This created a simple, empty project with everything you need to use NUnit and write some tests. The interesting thing I discovered is that Monodevelop includes its own Reflector utility. Going to the references of my NUnit project and double-clicking on nunit.framework, I got this:

Which is how I figured out I was using version 2.4.8. You can drill down into the assemblies and click on methods. I guarantee it; you will see code! Anyway, here's my test code:
1:
2: using System;
3:
4: using MyTest;
5:
6: using NUnit.Framework;
7: using SpecUnit;
8:
9: namespace MyTest_spec
10: {
11: [TestFixture()]
12: [Concern("MyClass")]
13: public class when_changing_the_string_of_my_class : ContextSpecification
14: {
15: [Observation]
16: public void should_persist_the_new_string()
17: {
18: myClass.MyString.ShouldEqual("Hello, world!");
19: }
20:
21: protected override void Because ()
22: {
23: base.Because ();
24: myClass.MyString = "Hello, world!";
25: }
26:
27:
28: protected override void Context ()
29: {
30: base.Context ();
31: myClass = new MyClass();
32: }
33:
34: protected MyClass myClass;
35: }
36: }
Please note that Monodevelop default to using the .Net 2.0 framework. You will have to change this to .Net 3.5. Right-click on each one of the projects of your solution, select Options and go to Build/General. Change the runtime version to .Net 3.5, like shown below:

I've got my class, I've got my spec. Now I need to run the tests and see if this whole thing works on Linux! So I compiled... And BAM! I got an error. The compiler complained that SpecUnit was expecting the 2.4.6 version of NUnit. The problem is, as you've seen higher in this post, I was using nunit-2.4.8. I went back online and downloaded the SpecUnit code, thinking I'd recompile it with the 2.4.8 dlls of NUnit. I found the solution file (SpecUnit was created with Visual Studio, so I was looking for a .sln file) double-clicked on it and crossed my fingers... It worked! Monodevelop loaded the entire SpecUnit solution! All I had to do then was to replace the nunit.framework references with the newer ones from the 2.4.8 version, which were conveniently located with all the other regular .Net references. Recompile and voila! A brand new SpecUnit, ready to roll!
To tell you the truth, I wasn't expecting Monodevelop to load a .sln file. Later, reading the feature list of Mono and Monodevelop, I saw that Monodevelop fully supports MSBuild and even defaults to it. Nice! Embrace, extend, and... er... isn't that was Microsoft is supposed to do? Interesting to see somebody else doing it!
I replaced the old SpecUnit reference with the new one, compiled... And BAM! Another error! This time, the compiler was not too happy with my use of the extension method ShouldEqual, which was otherwise recognized correctly by the editor. However, the compiler kept complaining. After double-checking that all my projects were compiling for the .Net 3.5 framework, I googled the problem and found out that you have to include System.core in your references, which is not automatically done by Monodevelop. And that did the trick, the solution compiled!
I just had commited a heresy. I had just put a DLL on my pure, pristine Linux system. A DLL! No, even worse: two DLLs! I grapsed for something to hold on to. When the oily feeling that tainted my soul finally subsided, I ran the test:

It passed!
Now, this is really cool! I look forward to doing more with Mono. Hopefully, more and more developers will start using it. So far, the experience has been good, but I miss ReSharper and the ability to run tests from within the IDE. Monodevelop allows us to write plugins, so anybody up for a a R# clone on Monodevelop?
Thanks for reading.
Posted
May 25 2009, 09:01 PM
by
Louis Salin