WatiN and Vista
Been meaning to post this for a while now but haven't found the time. When trying out WatiN on my Vista machine I kept receiving the following error message:
WatiN.Core.Exceptions.TimeoutException: Timeout while 'waiting for main document becoming available'"
Turns out that WatiN and Vista don't play nicely together and on Vista you will need to disable UAC in order for WatiN to execute correctly.
It kept me guessing for an hour so I thought I would post regarding this matter. Expect more posts on WatiN soon...
UPDATE: Or, if you don't want to disable UAC, make sure your test runner is running as Administrator
DDD6 - Post Event
What an amazing day!! Having enjoyed DDD3, DDD4 and DDD5 yesterday I was given the chance to speak at DDD6! I felt honoured that I was given the chance and really enjoyed walking around in my green DDD t-shirt. My session was one of the last in the day but I managed to pull in a room full of attendees (about 50) which was amazing and thank you to everyone who attended. The day goes so much quicker when your speaking!
My session kind of went to plan, words came out my mouth and I finished on time but I did forget some points and think I could have explained things better (I think my demo scenario could have been better). But it was great experience and I will take the improvements onboard for when I do a similar session at NxtGenUG Cambridge. Paul Lockwood who did a CCNet talk also attended my session - Read his thoughts @ http://dotnetworkaholic.com/ddd6-uk-code-camp/
As for the rest of the day, I attended some great sessions. My favourite session of the day (apart from mine) was Why do I need an Inversion of Control Container? by Mike Hadlow, good content and well presented. After the day, I went for one or two well deserved beers and the geek dinner which was great and spoke to some really nice people. Cheers to Zi for organising that.
Demo: TestingApplicationsWithMbUnit.zip
Slides: TestingYourApplicationsWith Mbunit.pptx.zip (UPDATE: Download link now works. Sorry)
Finally, don't forget to fill out your feedback - http://www.developerday.co.uk/ddd/feedback.asp. Can't wait for the next conference!
Download Camtasia Studio 3.1.3 for Free
Darren Straight has blogged about getting Camtasia Studio 3.1.3 for free! This isn't the latest version, but works perfectly fine for creating the odd screencast.
Very cool! Thanks Darren.
Download Camtasia Studio 3.1.3 for Free « Darren Straight’s Blog
Expect some screencasts over the next month.
Labels: Screencasts
Linq to SQL Beta 2 to RTM Diagram Error
After installing RTM on my laptop, I all of my Beta 2 Linq to SQL diagrams refused to open and save the error.
"Cannot load 'path': Error encountered, check Error List window for details".
The error list had the following error
"Error 2 There is no Unicode byte order mark. Cannot switch to Unicode. 1 1 TestingLinqToSQL"
In the properties for the dialog, it was already set as Unicode. To fix this, in the xml header for the diagram, in Beta 2 it was "<?xml version="1.0" encoding="utf-16"?>". RTM requires the encoding to be utf-8 (<?xml version="1.0" encoding="utf-8"?>). Set the xml declaration to this, save and reopen and your diagram should be working again.
Labels: Linq
How To Unit Test - Linq to SQL and Mocking
"All problems in computer science can be solved by another level of indirection" Butler Lampson (Or Abstraction as some people refer to it as)
Over the last few posts, I have been covering how to unit test various topics, in this post I will cover Linq to SQL. I've been thinking about this for a while, but never had chance to post about it. Various people have spoken about this before, but I thought I would give my view. I'm going to discuss how to unit test systems involving Linq to SQL, how to mock Linq to SQL, how this will come into play with the new ASP.net MVC Framework and how TypeMock might have the answer.
Scenario
For this post, I decided to implement a small part of a shopping cart. You can return a list of categories, a list of products for each category and the product itself.
Unit Testing Linq to SQL
In my previous post, I discussed how to unit test Linq to XML and mentioned how it really isn't that different to any other system. Linq to SQL is similar in the fact that you can easily ignore the underneath implementation (Linq) when unit testing, however I'm going to focus more on how to decide the system and how it all should hang together.
Like in any Linq to SQL implementation you will need a data context. While you could unit test this implementation, I always prefer to test it as part of a higher layer as its generated code to give the tests more context and more meaningful for the system. The most important part of the system will be how we actually access the DataContext, retrieve the data and make sure that it can be effectively unit tested.
In my system I will have my HowToUnitTestDataContext generated by the Linq to SQL Designer. I will then have a ProductController which will talk to my DataContext and return the generated object. Unlike with SubSonic, we can return the designer generated objects as they are just POCO (Plain Old C# Objects). I will then have a set of unit tests targeting the ProductController. We are not doing any mocking at this point and all of our unit tests will hit the database.
First test, create a data context and ensure it has a connection string. This ensures everything is setup correctly.
[Test]
public void CreateDataContext_ConnectionString_ReturnsDataContextObject()
{
HowToUnitTestDataContext db = ProductController.CreateDataContext();
Assert.IsNotNull(db);
Assert.IsNotNull(db.Connection);
}
All the method does is initialise a data context and return it to the caller. The next test requests a list of all the categories from the database. However, because we haven't populated anything yet it should just return an empty list.
[Test]
public void GetCategories_NoContent_ReturnEmptyList()
{
List<Category> categories = ProductController.GetCategories();
Assert.IsNotNull(categories);
Assert.AreEqual(0, categories.Count);
}
We now have a base structure in place and can start filling in the details. The following test first inserts a category into the database (code is in the solution which you can download at the bottom of the post). It then requests all the categories from the database and ensures that what we returned was correct. We then use the MbUnit RollBack feature to ensure the database is left in the same state as it was before the test. The rollback works perfectly with Linq to SQL!
[Test]
[RollBack]
public void GetCategories_SimpleContent_ReturnPopulatedList()
{
InsertCategory();
List<Category> categories = ProductController.GetCategories();
Assert.IsNotNull(categories);
Assert.AreEqual(1, categories.Count);
Assert.AreEqual("Microsoft Software", categories[0].Title);
}
The code for GetCategories() is a simply Linq to SQL statement which returns a generic list.
public static List<Category> GetCategories()
{
HowToUnitTestDataContext db = CreateDataContext();
var query = from c in db.Categories
select c;
return query.ToList();
}
The next important test is the one which returns product information. Here, we use a tested GetCategory method to return a particular category. We then insert a temp product into the database for that category, meaning that we now have a known database state to work with. The test then simply verifies that when given a category we can return all the products in the database for it.
[Test]
[RollBack]
public void GetProductsForCateogry_ValidCategoryWithProduct_PopulatedList()
{
InsertCategory();
Category c = ProductController.GetCategory("Microsoft Software");
InsertProduct(c);
List<Product> products = ProductController.GetProductsForCategory(c);
Assert.AreEqual(1, products.Count);
Assert.AreEqual("Visual Studio 2008", products[0].Title);
}
The implementation of this method is a little bit more complex as it joins a ProductCategories table to return the products within the particular category.
public static List<Product> GetProductsForCategory(Category c)
{
HowToUnitTestDataContext db = CreateDataContext();
var query = from p in db.Products
join pc in db.ProductCategories on p.id equals pc.ProductID
where pc.CategoryID == c.id
select p;
return query.ToList();
}
The final method is to return a particular product based on its ID. It works in a similar fashion to the previous methods.
[Test]
[RollBack]
public void GetProductByID_ValidProductID_ReturnProductID()
{
InsertCategory();
Category c = ProductController.GetCategory("Microsoft Software");
InsertProduct(c);
List<Product> products = ProductController.GetProductsForCategory(c);
Assert.AreEqual(1, products.Count);
Product p = ProductController.GetProduct(products[0].id);
Assert.AreEqual(p.Title, products[0].Title);
}
In the implementation we then just return a single product using a lambda expression.
public static Product GetProduct(int productID)
{
HowToUnitTestDataContext db = CreateDataContext();
Product product = db.Products.Single(p => p.id == productID);
return product;
}
That pretty much covers unit testing basic Linq to SQL. Other parts of the system, such as the business layer or UI layer, can then talk directly to the ProductController to return all the information. However, this doesn't offer anything if you want to mock out Linq to SQL.
Mocking Linq to SQL
Unit testing Linq to SQL isn't very difficult, however mocking Linq to SQL is a different beast. As with SubSonic, the best approach to take is to abstract away from your database. In this case, I am going to add an additional layer in between my ProductController and my DataContext called LinqProductRepository which can then be mocked.
My first set of tests are focused on testing the LinqProductRepository which talks to my DataContext and as such my database. The tests are very similar to the above tests for ProductController. I always test this against the database to ensure that it will work effectively when its in production/live, with mock objects you can never have the same level of confidence.
LinqProductRepository m_ProductRepository = new LinqProductRepository();
[Test]
[RollBack]
public void GetCategoryByName_NameOfValidCategory_ReturnCategoryObject()
{
InsertCategory();
Category c = m_ProductRepository.GetCategory("Microsoft Software");
Assert.AreEqual("Microsoft Software", c.Title);
Assert.AreEqual("All the latest Microsoft releases.", c.Description);
}
To give you an idea of the implementation, the GetCategory method looks like this:
public Category GetCategory(string categoryTitle)
{
using (HowToUnitTestDataContext db = CreateDataContext())
{
Category category = db.Categories.Single(c => c.Title == categoryTitle);
return category;
}
}
In order to make the ProductRepository mockable it is required to implement an interface. The interface is very simply, as shown:
public interface IProductRepository
{
List<Category> GetCategories();
Category GetCategory(string categoryTitle);
List<Product> GetProductsForCategory(Category c);
Product GetProduct(int productID);
}
We now have a fully implemented and tested ProductRepository so we can create the ProductController. To start with, in my ProductControllerTests I setup the variables and the [Setup] method for each test. This ensures that we have our MockRepository (via RhinoMocks) to hand, a copy of our mocked IProductRepository together with our stub category and product. These two objects are simple well known objects (for the system) which we will return from our mocked methods. I'm using parameter injection to set the mocked repository on the ProductController which will be used during the tests. By using a parameter we can have a default implementation for our production code but a way for our test code to injection the mock object.
MockRepository m_Mocks;
IProductRepository m_ProductRepos;
Category m_MockedCategory;
Product m_MockedProduct;
[SetUp]
public void Setup()
{
m_Mocks = new MockRepository();
m_ProductRepos = m_Mocks.CreateMock<IProductRepository>();
ProductController.ProductRepository = m_ProductRepos;
m_MockedCategory = MockCategory();
m_MockedProduct = MockProduct();
}
We can then write our unit tests based on this information which will be similar to our previous units tests as they are implementing the same requirements. Within this test, we setup our expected return for the method GetCategories on our ProductRepository, this simply uses C# 3.0 Collection Initialises to create a list with one item, the stub category. We can then execute our test/asserts against the ProductController to view it is all linked correctly and working as expected.
[Test]
public void GetCategories_SimpleContent_ReturnPopulatedList()
{
using (m_Mocks.Record())
{
Expect.Call(m_ProductRepos.GetCategories()).Return(new List<Category> { m_MockedCategory });
}
using (m_Mocks.Playback())
{
List<Category> categories = ProductController.GetCategories();
Assert.IsNotNull(categories);
Assert.AreEqual(1, categories.Count);
Assert.AreEqual("Microsoft Software", categories[0].Title);
}
}
The ProductController simply passes the call onto our ProductRepository, which is set using a parameter in our test Setup.
private static IProductRepository m_ProductRep = new LinqProductRepository();
public static IProductRepository ProductRepository
{
get { return m_ProductRep; }
set { m_ProductRep = value; }
}
public static List<Category> GetCategories()
{
return ProductRepository.GetCategories();
}
This allows us to use the ProductController with a mock object. ProductController could be/do anything and by going via the LinqProductRepository we can use mock objects to save us accessing the database. In our real system, we would use the real tested LinqProductRepository object.
ASP.net MVC and Linq to SQL
Recently there has been a lot of buzz around the new ASP.net MVC framework the ASP.net team are releasing (CTP soon). If you haven't read about this, Scott Guthrie has done a great post on the subject.
However, Scott Hanselman did a demo of the MVC framework at DevConnections and has posted the source code online here - DevConnections And PNPSummit MVC Demos Source Code. Demo 3 and 4 is about TDD and uses mock objects and Linq to SQL.
The layout is as follows:
The BlogController talks to a IPostRepository object which is either LinqPostRepository or TestPostRepository. They use a Stub object instead of a mock object, but the architecture is the same as my system. I would just like to say I didn't just copy them :)
From this demo code, it looks like the way to mock your data access layer will be to use this approach.
Mocking the DataContext
The thing which first struck me about this was why couldn't we just mock the DataContext itself instead of messing around with Repositories and Controllers. The first answer was that it didn't implement an interface, but that's a simple fix. The second problem is that the data context returns everything as System.Data.Linq.Table<>, and this cannot be mocked. It does implement an ITable interface, however you cannot cast another object implementing ITable to Table.
Ayende, creator of Rhino Mocks, wrote a post called Awkward Testability for Linq for SQL which covers why it cannot be mocked. Its a shame the Linq team didn't think about TDD and Mocking the repository as it would have made a big difference to the system design. Maybe this is a lesson for anyone creating an API at the moment - think about testability! I think the ASP.net team have realised this.
Mocking with TypeMock
That all said, it looks like TypeMock might be able to provide an answer. TypeMock is a mocking framework, however is extremely powerful as it can mock any object within your system, it doesn't care about the implementation or if there is an interface available. It can simply mock anything. I will be looking at TypeMock more over the next few weeks, but before then visit their site. It's not free (30 day trail available), but if you need to do this type of mocking then it really is your only solution and it can greatly increase your test coverage and your test suite as a whole.
You can read the initial ideas over on their blog - Eli Lopian’s Blog (TypeMock) » Blog Archive » Mocking Linq - Preview. Going in depth on TypeMock and Linq deserves its own post, however I couldn't resist posting some code now.
Below, we have a test which mocks out querying a simple list. Here, we have a list of customers and a dummydata collection. Our actual Linq query is against the m_CustomerList, however TypeMock does some 'magic' under the covers and tells the CLR that the query should just return the dummyData. As such, instead of just returning the one customer record, we are returning the two dummy data records. How cool!!!
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
[Test]
[VerifyMocks]
public void MockList()
{
List<Customer> m_CustomerList = new List<Customer> {
new Customer{ Id = 1, Name="Dave", City="Sarasota" },
new Customer{ Id = 2, Name="John", City="Tampa" },
new Customer{ Id = 3, Name="Abe", City="Miami" }
};
var dummyData = new[] {new {Name="fake",City="typemock"},
new {Name="another",City="typemock"}};
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
// Mock Linq
var queryResult = from c in m_CustomerList
where c.City == "Sarasota"
select new { c.Name, c.City };
// return fake results
recorder.Return(dummyData);
}
var actual = from c in m_CustomerList
where c.City == "Sarasota"
select new { c.Name, c.City };
Assert.AreEqual(2, actual.Count());
}
But it gets better! Given our original ProductController (no repositories, mocks, fakes, stubs) we can tell TypeMock that for this statement, always return the dummyData. As such, the ProductController never hits the database.
[Test]
[VerifyMocks]
public void MockDataContext()
{
Category category = new Category();
category.id = 1;
category.Title = "Test";
category.Description = "Testing";
List<Category> dummyData = new List<Category> { category };
using (RecordExpectations r = RecorderManager.StartRecording())
{
// Mock Linq
List<Category> mocked = ProductController.GetCategories();
// return fake results
r.Return(dummyData);
}
List<Category> categories = ProductController.GetCategories();
Assert.AreEqual(1, categories.Count);
Assert.AreEqual("Test", categories[0].Title);
Assert.AreEqual("Testing", categories[0].Description);
}
Feel free to download the solution and debug the methods to see it for yourself, I think its cool.
Summary
In summary, I hope you have found this post useful and interesting. I've covered how to unit test your Linq to SQL code and how you go about mocking Linq to SQL. I then finished by giving you a quick look at what TypeMock can offer. It is possible to mock Linq to SQL, however it's not as simple as it could be. If you have any questions, please feel free to contact me.
Download Solutions - TestingLinqToSQL.zip | TestingLinqToSQLMock.zip | TestingLinqToSQLTypeMock
Labels: ASP.net MVC, Linq, MbUnit, TDD, Testing
NotifyIcon and Always Hide setting
Yesterday, I had another one of those moments with the NotifyIcon class in C#.
During testing, if the icon was set to always hide under Windows XP then it would simply never display in the task bar. This I thought was very strange as it should be in the systray, just not visible when its in the compact state.
The reason? Well on a balloon close event I would also remove the icon from the systray as it had served its purpose. However, when an icon is set to Always Hide, when a balloon tip is shown it is instantly closed (by XP Shell) which causes the balloon close event to be raised which in turn removes the icon from the systray.
I should have realised sooner but simply didn't link the two actions. Next time in situations like this, always check events which hook up to the close event.
Labels: C#
How To Unit Test - Linq To XML
Now that I'm back from TechEd, it's time to continue my series of "How To Unit Test" posts. In this post, I've decided to have a quick look into Linq to XML and how that could be unit tested. I've decided to pick the nice standard sample for Linq to XML - A Rss Reader :). This also follows on nicely from my previous post on How To Unit Test Using SubSonic and Rhino Mocks.
Unit testing Linq to Xml is no great big secret. The fact that you are performing Linq queries under the covers doesn't really affect your unit tests, but it's still quite interesting.
To start with, I'm going to be using the BBC News feed as my sample xml feed to query. My first test is to return an RssChannel object which had a url and title. Note, I'm not implementing all the properties as that would get very boring very quickly.
[Test]
public void GetRssChannel_StandardRss_ReturnDataRssChannel()
{
RssProcessor rss = new RssProcessor();
RssChannel chan = rss.GetRssChannel(TestHelper.url);
Assert.AreEqual(TestHelper.url, chan.Url);
Assert.Contains(chan.Title, "BBC");
}
The implement on the method then simple queries a XDocument, creates my RssChannel object and returns it to the caller.
public RssChannel GetRssChannel(string url)
{
XDocument x_Feed = XDocument.Load(url);
var feeds = from f in m_Feed.Elements("rss").Elements("channel").Take(1)
select new RssChannel
{
Title = f.Element("title").Value,
Url = m_Url
};
return feeds.First();
}
The next method does a similar function but returns a RSSItem for the position in the document (Linq to XML is great for doing queries like this).
[Test]
public void GetRssItem_RssFeed_ReturnsASingleRSSItem()
{
RssProcessor rss = new RssProcessor();
RssItem item = rss.GetRssItem(TestHelper.url, 1);
Assert.IsNotNull(item);
Assert.IsNotNull(item.Title);
}
The query would be:
var feeds = from f in m_Feed.Elements("rss").Elements("channel").Elements("item").Skip(itemPosition - 1).Take(1)
select new RssItem
{
Title = f.Element("title").Value
};
Instantly we can see from the tests that we can do a bit of refactoring. Firstly, we can move the creation of the RssProcessor into a [Setup] method. We can also give the Url for the feed as a parameter in the constructor. This makes our test code cleaner as there is less duplication, but also more readable as we are focusing more on the intent of the tests.
The complete solution can be downloaded at the end of the post, however there is one more test which I want to refer to.
The following returns an RssFeed object which has a reference to the RssChannel and a List<RssItem>.
[Test]
public void GetRssFeed_EntireFeed_ReturnsChannelAndItems()
{
RssFeed feed = m_Rss.GetFeed();
Assert.IsNotNull(feed.Channel);
Assert.Contains(feed.Channel.Title, "BBC");
Assert.GreaterThan(feed.Items.Count,0);
}
The test works fine, however based on the implementation on the existing tests, each method loads their own Rss feed/XDocument. This is great for isolation, but doesn't work well when you put it all together as loading a single feed will cause it to actually be loaded three times - that simply doesn't scale.
The solution was to have a LoadFeed method on the RssProcessor which would be called before GetFeed(). This could also allow for a single object to be used for returning multiple feeds. Note for future: My first test should really have been for this method to make sure I can actually receive an object to work with before querying it.
m_Rss.LoadFeed(TestHelper.url);
Having this single method as the way to load and return the Xml makes mocking very easy. Following the approaches in previous posts, I created myself an IFeedGetter object, with a property to injection a mock if required on my RssProcessor. The load method then simply passes it's call onto the IFeedGetter object.
public XDocument LoadFeed(string url)
{
m_Url = url;
m_Feed = m_FeedGetter.GetXDocument(url);
return m_Feed;
}
I can then create a stub feed getter to be used during unit testing.
public class StubFeedGetter : IFeedGetter
{
public System.Xml.Linq.XDocument GetXDocument(string url)
{
return XDocument.Load(System.Xml.XmlReader.Create(new System.IO.StringReader(GetFakeXml())));
}
}
So that's it, we have now unit tested our complete Rss implementation using mocks and Linq to XML! If you need support in getting this to work, please give me a shout.
Download Solution: HowToUnitTest_MockLinq-ToXml.zip
Disabling Secure Desktop without disabling UAC
While at TechEd, I noticed one or two of the speakers had a different setup with UAC. When the UAC was activated their screen would not flicker and go black, instead just the UAC dialog would appear.
I like UAC, I think its important when an admin action is about to be executed and I like the way applications now work without administration permissions being required. However, I do find the flicking annoying.
A quick search on Google, I found that it's secure desktop which causes the flicking to occur, or should I say is the reason why the flicker occurs. Secure desktop only allows trusted processes running as SYSTEM to be executed It has been explained in more detail here.
However, this does make your system less secure as part of making UAC secure is the secure desktop which blocks malicious applications running. By removing this layer, you are opening your system up to attack. In one of the talks at TechEd, Michael Howard said how important the different layers are within Vista security. But, if this stops you turning off UAC completely, then its a good thing.
To disable secure desktop, load the Local Security Policy (type it in the start menu) and under Local Policies > Security Options there is an option to disable "Switch to the secure desktop when prompting for elevation".
You will now have a very different UAC experience.
More information: http://www.howtogeek.com/howto/windows-vista/make-user-account-control-uac-stop-blacking-out-the-screen-in-windows-vista/
Labels: Vista
TechEd Developers 2007: Round up
TechEd Developers is over. I wasn't very good at real-time blogging (it's difficult on a mobile) so I thought I would summarise it in a single post.
Major Announcements
Visual Studio 2008 is being released by the end of the month. Rumours are that it will in-fact be the 15th of this month.
SQL Server 2008 CTP 5 - Should be due out this month, but I would expect one or two weeks.
Sync Framework - Microsoft have released a sync framework for allowing applications to work effectively in an offline fashion.
ASP.net MVC - The ASP.net MVC framework will be out in three weeks (22nd?). More on this in a later post.
Windows Live Tools for Microsoft Visual Studio - Released @ http://dev.live.com/tools/
TechEd Sessions online next week. This is great news for all the attendees (not so great for everyone else as it's attendee only access). There were some sessions which I wish I had went to but clashed with something more important.
Sessions
I found the sessions quite hit and miss. Some sessions where amazing with Roy Osherove being the best speaker for me but others seemed very high level and marketing focused which I wasn't really expecting.
The Party
On Wednesday night there was the country party. This was a very enjoyable evening, lots of good food, free beer with great company. However getting up for Thursday sessions was difficult ;)
The Swag
The swag was good, NxtGenUG were there dong one or two game shows. Some of the companies where giving away freebies but managed to grab a few interesting items - mainly the The Security Development Lifecycle book.
Summary
Generally, it was a great week. Red Gate covered a lot of the cost which was amazing and there were 14 of us attending in total so there was great company. Hopefully I will be able to attend next year. One thing, I will take a laptop so I will have less stuff to catch up on when I return. Might be a reason for a new laptop by then....
Labels: TechEd
Windows Live Writer: Out of Beta
Windows Live Writer has finally been released without a beta status. It is now under the title of Windows Live Writer 2008 (v12).
I recommend you go out and download the latest version, it is a really good piece of software. Well done to the team.
Download it from:
http://get.live.com/writer/overview
More information on the team's blog:
Windows Live Writer- Out of Beta
Labels: LiveWriter
TechEd Developers 2007: First Day - All swagged out
Labels: TechEd





Social networks
Twitter GitHub SlideShare