#.think.in
learn.create.enjoy

Silverlight Designer Developer Network 27th Nov 2008

November 30, 2008 22:59 by brodie

image

The first Silverlight Designer and Developer Network (SDDN) meeting, held last Thursday, was set to be a great evening with Shane Morris and Jonas Follesø lined up for some presentations, over 80 people in attendance and a $20K MSDN subscription up for grabs.

One of the organisers Jordan Knight opened the evening in front of an impressive looking SDDN screen saver with bouncing stars/balls which definitely distracted my attention on a number of occasions.

Of the 80 people there only 6 owned up to being designers, which was anticipated, but disappointing for the organisers.  Microsoft has never really focused on designer software before the Expression product suite and it's fairly obvious that Silverlight won't hit the mainstream unless they can get designers onboard using their products alongside developers.  They are hoping for more designers to come along to future meetings ... personally I don't know of any designers geeky enough to attend a user group meeting, but hopefully some more will show up in the future.

Other than introducing the evening Jordan mentioned...

  • possibilities of more advanced topic talks and perhaps even breaking presentations into multiple streams
  • talk of a low cost training day to be held next year
  • a call for speakers in future meetings - hmmm

 

Shane Morris - Keynote

Shane's presentation was about User Interface Design and how to create a great user experience, and how Silverlight can help to achieve those great experiences.

His key take away was "you are not your user" which is a fair enough statement and one that is often forgotten when creating software.  A software project can easily produce a functionally complete product but be completely useless to the end user if not enough thought is given to the user interface/experience.

He pushed the idea of user centred design and how designers/developers need to understand how the people they are writing the software for really work - their environment, tasks, tools, skills, fears, motivation, etc.  The best way to achieve this is by observing your users at work.  In my first job I was lucky enough to spend some time with one of our clients and observe them using our software. It's very much an eye opener and really makes you think a lot more about the user interface.

He finished by mentioning a couple of competitions that are around at the moment which pricked the ears my college Tarn, who recently came second in the Devsta competition.

 

The break in between the two speakers allowed many of the attendees to have a go on one of the only Microsoft Surface computers in Australia.  I jumped straight in and as pretty impressed, definitely looking forward to these machines becoming more mainstream, and better still being able to write some software for one.

 

Jonas Follesø - SIlverlight @ PDC

Tarn and I had seen one of Jonas presentations recently at the last VIC.NET meeting and were extremely impressed, so we were expecting more of the same - we were not disappointed.

In a jammed packed marathon session he took us through some of the goodies that came out of the PDC with regards to Silverlight;

The toolkit currently consists of 12 controls and 6 themes which you can view when you download the sample application from the codeplex site. Apparently there will be a monthly toolkit drop containing more controls/themes as they become available, all open source and unit tested!

The Mesh-enabled Silverlight application was based on Jonas' Divelog example and although he blazed through the demo we got the general gist of it's power.  Will have to get a key to play around with that a bit more. See...

I was very impressed by the Silverlight Business Application Framework and for the first time it really sunk in how full business apps could be done well as an RIA.  It made me instantly think of rewriting our Adminstration website ;-) Can't wait for it to be fully released.  

 

So all in all a good first meet, with much promise for future.  Oh, and no we didn't win the prize - the guy sitting next to us did, and I had lent him my pen to fill in the ticket - douh! ;-)

The sessions were recorded and will be available shortly - I'll update the links here once they're done.

Here are a few pictures taken that night


Tags:
Categories: Reviews
Comments (4)

SharpWeblog - Iteration 1

November 29, 2008 16:28 by tarn

I've finished all the initial requirements so I'll briefly describe how its going.

The Data Layer

The data layer interface has methods to find, create, update and delete stateless model objects. The data layer is implemented with Linq to Sql. As the interface uses model data objects, the data layer implements the repository pattern by mediating these objects with the Linq to Sql classes.

This is nice as it means the rest of the application doesn't have a dependency on the data layer implementation. This is good as I don't want to have to deal with Linq to Sql classes through-out the entire application. There are tests verifying what I would consider a more sane object model is correctly implemented by the data layer.

I personally don't think Linq to Sql should be considered as an ORM for most web applications; It has no built in way of modeling many to many relationships and it's much more difficult to use than most other ORM I've worked with. I'm looking forward to trying the new Entities Framework, and hope they have finally made a legitimate ORM.

Routing

I'm a big fan of both being able to write routing logic and routing logic tests so easily. I highly recommend writing tests verifying your routes. I briefly discussed how this is done in my previous post about testing this project. The requested route is tested against all the routes in sequence until a match it found. This means its very easy to add a route that inadvertently catches a route that was supposed to be mapped by another route further down the sequence.

I think TDD is really important here as the routing can quickly get quite complicated. Adding unit tests verifying specified routes are mapped to the correct controller and actions will protect your routes. It's also generally a quicker development cycle writing some route tests and then writing the route logic than writing the route logic and testing it in the browser.   

If you insist on testing your routes in the browser or just want to see how specific are mapped in action, Phil Haack has a neat little route tester tool that renders the route test information in the browser for any URL on your site you enter.

Views

So far there has been no work done on the UI and the views are all pretty basic. I'm using C# with strongly type ViewPages, but I would like to consider using a dynamic language later in the project.

I'm a huge fan of the templated ActionLink helper method, I included the ASP.NET MVC Futures assembly without hesitation when I realised it wasn't included in the Beta.

<%=Html.ActionLink<HomeController>(m => m.Category(category),category) %>

 

I'm a little more nervously on the fence with regard to the RenderAction method which allows you to call an action on the controller from within a view to render a control. I can see the why its there; It provides a lot of flexibility for making controls that can be responsible for getting there own data and can be used by any view. This also means these user control controller actions can be tested separately. On the other hand it appears to be way to get around the MVC pattern where in many cases the controller itself could call off to get the additional information and pass it down to view.

<%Html.RenderAction<HomeController> 
(m => m.PostDetail(ViewData.Model.SelectedPost));%>

 

If I could call a view from within another view and pass it a model from the data already in the calling view I would be a lot more comfortable with it (You probably can do that, I haven't worked it out yet). That way there would be a nice way to call controls with model data without calling methods on the controller from the view.

EDIT: As soon as I tabbed to Visual Studio after posting this I noticed the login control from the template renders a user control using RenderPartial from the view. The user control inherits from ViewUserControl and can be templated. An overloaded RenderPartial method allows you to pass model data to the view. I've fallen to the lets get on with coding side of the fence.

<% Html.RenderPartial("LoginUserControl"); %>

 

Membership and Roles

It wasn't in my initial requirements, but the MVC VS2008 Beta template comes with some login in and registration pages using the default SQL Server Membership provider. I am looking to leverage all the technologies I can to build this site, so I decided I would use the default provider, if I could use it and keep the code very testable.

In the default template a database is generated with the membership and roles tables and stored procedures used by the default membership provider already created. As I already had a database, I used a tool called aspnet_regsql to add the tables and procedures to my database. The tool is part of the .NET framework and can also be used to generate scripts and works with SQL Server Express.

I had mixed emotions when I found this in the controller from the template. I liked that they had thought about testing the controller (no tests are actually included).

// This constructor is not used by the MVC framework but is instead provided for ease
// of unit testing this type. See the comments at the end of this file for more
// information.

public AccountController(IFormsAuthentication formsAuth, MembershipProvider provider)
{
    FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
    Provider = provider ?? Membership.Provider;
}

.. 

// The FormsAuthentication type is sealed and contains static members, so it is difficult to
// unit test code that calls its members. The interface and helper class below demonstrate
// how to create an abstract wrapper around such a type in order to make the AccountController
// code unit testable.

..

 

That great! Its a pattern I use in the project to avoid dependencies and improve testability, the only problem is I don't think they've gone far enough. I'm going to take it further and create a wrapper around Provider so I can mock it and not have a dependency on System.Web in my controller unit tests. 

EDIT: After writing this post I found I could reference System.Web in my tests and not have a development web server fire up when the tests run. I was a little surprised by this, and now I'm not sure what does fire up the development web server. I'll post an update on this when I understand it more clearly.   


Tags: ,
Categories:
Comments (0)

SharpWeblog - Testing

November 24, 2008 15:54 by tarn

I'm right into the coding for this project at the moment, but the iteration one requirements are all complete so its probably a good time to write some posts and reflect on what has been implemented so far.

As specified this project is use TDD for development. There has been a lot of work put into ASP.NET MVC to make it a most testable framework. I would like to discuss how various parts of this project have been tested.

I am using Microsoft Unit Test Framework and MOQ for testing this project. I had never used MOQ before, but I love it. For those that don't know about MOQ its another mock testing framework, the thing I love about it is it uses C# 3.5 so you can do a lot with lambda expressions.

Controllers

In the controller tests a real controller is created with a mocked IWeblogRepository interface. This means the controller can be tested independent of an IWeblogRepository implementation. 

[TestInitialize]
public void Setup()
{
    _mockRepository = new Mock<IWeblogRepository>();
    _controller = new HomeController(_mockRepository.Object);
}

Testing controllers is really testing two things, firstly that the controller renders the correct view and secondly it sends the right data to that view. The tests shown here validate the "Post" action on the HomeController.

In this test the mock repository is setup to return a post when GetPost("Test-Post-1") is called on it. When we call the controller with these parameters we expect it to make the specified request to the mock repository. This test ensure that when a post is found that "Post" view is rendered.  

The sharp eyes will notice that I'm not using the date parameters to find the post from the repository. That functionality has not been implemented in this iteration.

[TestMethod]
public void Post_FindsPost_RendersPostView()
{
    _mockRepository.Expect(m => m.GetPost(It.Is<string>(i => i == "Test-Post-1")))
                   .Returns(new PostModel());        
    ViewResult result = _controller.Post(8,8,8,"Test-Post-1") as ViewResult;
    Assert.AreEqual("Post", result.ViewName);
}

 

We can also test the correct data is being sent to the view. I personally like to separate these two tests, this may not be a universal opinion, but I think its best to keep unit tests short and I think these tests are clearly testing different expectations.

[TestMethod]
public void Post_FindsPost_ReturnPostViewData()
{
    _mockRepository.Expect(m => m.GetPost(It.Is<string>(i => i == "Test-Post-1")))
                   .Returns(new PostModel() {
                                                Title = "Test Post 1",
                                                Content = "Test Post Content 1"
                                            });        

    ViewResult result = _controller.Post(8, 8, 8, "Test-Post-1") as ViewResult;
    PostViewData data = result.ViewData.Model as PostViewData;
    Assert.IsNotNull(data);
    Assert.AreEqual("Test Post 1", data.SelectedPost.Title);
    Assert.AreEqual("Test Post Content 1", data.SelectedPost.Content);
}

 

Two additional test were added to test other expectation of the "Post" controller action. These test that the "Index" view is rendered when the action is called with invalid parameters or can't find the post. This functionality may change to display an error message or alternate posts when the request is invalid in later iterations.

[TestMethod]
public void Post_PostNotFound_RendersIndexView()
{
    _mockRepository.Expect(m => m.GetPost(It.Is<string>(i => i == "Test-Post-1")))
                   .Returns<PostModel>(null);
    ViewResult result = _controller.Post(8, 8, 8, "Non-Existing-Post") as ViewResult;
    Assert.AreEqual("Index", result.ViewName);
}

[TestMethod]
public void Post_InvalidRequest_RendersIndexView()
{
    ViewResult result = _controller.Post(null,null,null,null) as ViewResult;
    Assert.AreEqual("Index", result.ViewName);
}

 

Routes

Testing routes is testing Http Requests are correctly mapped to the appropriate controller actions with the appropriate parameters. The below is testing "~/Post/2008/10/20/Test-Post" request will call the HomeController with the Post action and will also correctly populate the parameters.

[TestMethod]
public void PostRoute_TestSuccessfullRoute()
{
    var routes = new RouteCollection();
    var context = new Mock<HttpContextBase>();

    context.ExpectGet(m => m.Request.AppRelativeCurrentExecutionFilePath)
           .Returns("~/Post/2008/10/20/Test-Post");

    SharpWeblogRouting.RegisterRoutes(routes);
    var routeData = routes.GetRouteData(context.Object);

    Assert.AreEqual("Home", routeData.Values["controller"]);
    Assert.AreEqual("Post", routeData.Values["action"]);
    Assert.AreEqual("20", routeData.Values["day"]);
    Assert.AreEqual("10", routeData.Values["month"]);
    Assert.AreEqual("2008", routeData.Values["year"]);
    Assert.AreEqual("Test-Post", routeData.Values["name"]);
}

 

I can write a more route tests to test other requests when I have features saying what should happen.

Data Layer

While I think its great we can "fake out" the IWeblogRepository to avoid using an actual implementation while testing other areas of the system, I strongly believe implementations of the IWeblogRepository should also be tested, separately.

The IWeblogRepository interface basically has methods to save, load, update and delete model objects in a data storage. In this case it is storing the data in a SQL Express 2005 database using LINQ to SQL.

NOTE: The model classes are just data objects that have no information about the data context or data state. This does result in some inefficiencies updating the database, but the design was chosen as it clearly separates the implementation of the data layer from the rest of the system.

Anyway here are some typical tests, no mocking required here.

NOTE: I think these tests should be written against an interface with our implementation injected in. This would mean the same tests could be applied to other IWeblogRepository implementations.

[TestMethod]
public void PostCRUD()
{
    // Create
    PostModel post = CreateTestPost();
    _repository.SavePost(post);
    
    // Read
    PostModel findPost = _repository.GetPost(post.Id);
    Assert.IsNotNull(findPost);
    ValidatePosts(post, findPost);

    // Update
    findPost.Content = "Updated Content";
    findPost.Title = "Update Content";
    _repository.SavePost(findPost);

    // Read Update
    PostModel findUpdatedPost = _repository.GetPost(post.Id);
    Assert.IsNotNull(findUpdatedPost);

    // Delete
    _repository.DeletePost(findUpdatedPost);
    PostModel findDeletedPost = _repository.GetPost(post.Id);
    Assert.IsNull(findDeletedPost);
}

 

While I generally like small tests, I think an objects CRUD tests are best tied up in one test because otherwise you end up testing "create" four times to setup for each of the other tests. I would also generally implement the entire CRUD of an object even if it wasn't all required just so as CRUD tests can be performed and each operation can be tested.

I have many more tests for the data layer but they are all pretty standard, so no point discussing them further here.

MetaWeblog

The MetaWeblog API has also been (partly, so far) implemented for this project. I will discuss the implementation further in another post but for now we'll talk about testing it.

The MetaWeblog is implemented in two clearly separate components. One part processes the XML-RPC request and invokes methods on a IMetaWeblog interface and returns XML-RPC responses to Http Response. The other is an implementation of the IMetaWeblog, both can be tested separately.

Testing the IMetaWeblog implementation is pretty straight forward. As the IMetaWeblog implementation uses the repository through the IWeblogRepository interface we can mock the repository and test the expected calls are made against the interface.

NOTE: Sharp eyes will notice I'm not validating the user name and password. This isn't yet implemented.

[TestMethod]
public void NewPost_InvokesSaveMethod()
{
    MWAPost post = TestHelper.CreateTestMWAPost();
    Mock<IWeblogRepository> repository = new Mock<IWeblogRepository>();
    SharpMetaWeblogAPI model = new SharpMetaWeblogAPI(repository.Object);
    model.NewPost("100", "TestUser", "TestPassword", post, false);
    repository.Verify(m => m.SavePost(It.Is<PostModel>(p => ComparePosts(p, post))));
}

We can also test the return values of the IMetaWeblog methods with a known responses from the IWeblogRepository mock.

[TestMethod]
public void GetPost_ReturnsRequestedPost()
{
    Guid id = Guid.NewGuid();

    PostModel post = new PostModel()
    {
         Title = "Test Title",
    };
    Mock<IWeblogRepository> repository = new Mock<IWeblogRepository>();
    repository.Expect<PostModel>(m => m.GetPost(id)).Returns(post);
    SharpMetaWeblogAPI metaWeblog = new SharpMetaWeblogAPI(repository.Object);
    MWAPost findPost = metaWeblog.GetPost(id.ToString(), "none", "none");

    Assert.AreEqual(post.Id.ToString(), findPost.postID);
    Assert.AreEqual(post.Title, findPost.title);
}

 

Being able to unit test the MetaWeblogFramework is cool, but I may have taken unit testing too far here, but I'll let you decide.

The MetaWeblogFramework had to be implemented against HttpContextBase, with an actual context object passed into the ProcessRequest method. An instance of IMetaWeblogAPI is injected into the constructor to allow the framework to call the interface methods on a real object after processing the request, kind of like a call back or an event. 

The structure of most of tests I have written so far is to mock a HttpContextBase request and send it to a real instance of MetaWeblogFramework which has been constructed with a mock IMetaWeblog API.

This way I can verify that with known HTTP requests and payloads the expected methods on the IMetaWeblog interface are called. The test below creates an XmlRpcRequest object which the HttpContextBase mock will return when the MetaWeblogFramework ProcessRequest method requests the HttpContext.Request.InputStream. The test expects the IMetaWeblogAPI.NewPost(..) method to be called with known parameters.

 

[TestClass]
public class MetaWeblogFrameworkTest
{
    Mock<HttpContextBase> context;
    Mock<IMetaWeblogAPI> api;
    Byte[] _output;

    [TestInitialize]
    public void Setup()
    {
        context = new Mock<HttpContextBase>();
        api = new Mock<IMetaWeblogAPI>();

        _output = new Byte[1000];
        context.ExpectGet(m => m.Response.ContentType).Returns("text/xml");
        context.ExpectGet(m => m.Response.OutputStream).Returns(new MemoryStream(_output));
    }

    [TestMethod]
    public void ProcessRequest_MockRequestNewPost_InvokesNewPostMethod()
    {
        MWAPost sentPost = TestHelper.CreateTestMWAPost();
        XmlRpcRequest mockRequest = new XmlRpcRequest()
        {
            MethodName = "metaWeblog.newPost",
            Params = new List<Param>()
            {
                new StringParam("TestBlogId"),
                new StringParam("TestUserName"),
                new StringParam("TestPassword"),
                new PostParam(sentPost),
                new StringParam("False"),
            }
        };
        context.ExpectGet(m => m.Request.InputStream).Returns(mockRequest.CreateStream());
        MetaWeblogFramework framework = new MetaWeblogFramework(api.Object);

        framework.ProcessRequest(context.Object);
        
        api.Verify(m => m.NewPost("TestBlogId", "TestUserName", "TestPassword", It.Is<MWAPost>(a=>sentPost.Match(a)) , true));
    }
 
    ..

}

 

Testing the MetaWeblogFramework was a little difficult, and I had to create a whole range of additional objects and methods to perform the tests. I might re-visit the MetaWeblogFramework implementation later in the project and re-write it to be more testable.

Conclusion

Well I managed to test a whole range of components in this ASP.NET MVC project, but my overall coverage is still pretty low (32% over the entire project). I'll keep you updated with how testing is going though-out the project and I'll try to get those coverage stats up by the drop of the first iteration this week.

 

image


Tags: , , , ,
Categories:
Comments (1)

#.think.in infoDose #8 (17th Nov - 22nd Nov)

November 24, 2008 09:36 by brodie

Announcements

Management/Process

Architecture

ASP.NET

jQuery

Silverlight

XML

Tools

Books

0000@934_934-41266165e4ae7592

Amazon.com Essential Windows Communication Foundation (WCF) For .NET Framework 3.5

0001@934_934-41266169f8a86420

Blog Blazers 40 Top Bloggers

Singularity Watch

Other

Funny...


Tags:
Categories:
Comments (3)

SharpWeblog Project

November 21, 2008 14:47 by tarn

Introduction

I've just started a small project building a simple weblog site using ASP.NET MVC. I know there are heaps of blog sites out there but I thought it would be a good project to get familiar with ASP.NET MVC, JQuery and Silverlight 2.

I don't like writing about projects I'm going to build, but I'm hoping I can get a couple of the guys from work involved to share the learning and the work. I'm also going to hassle a few graphic designers I know and try to get little free consulting and maybe even some design work.

It will be used it to drive this blog instead of BlogEngine.NET which we are currently using.

To keep things simple the project will use the database schema and parts of the Metaweblog API implementation from the BlogEngine.NET project. LINQ to SQL will be used to quickly get some ORM mappings to the database schema. It will also use the standard ASP.NET Membership and Roles providers for SQL Server. Some Silverlight 2 will be added for some cool menus and navigational controls.

Tools, Technologies and Methodologies

The project will use TDD, Agile methodologies and identify design patterns where appropriate.

For now the code will be hosted on our internal Subversion server, but I would like to move it CodePlex eventually. I will move it sooner if anyone else is interested in checking out the code or contributing to the project. I would like to use a build machine, but I'm not sure if there is support for this at CodePlex, but we'll find out.

The project will be developed with .NET 3.5 SP1 and ASP.NET MVC Beta. The Microsoft Unit Test framework will initially be used for unit testing but a Mock Testing framework may be introduced later.

The project should be able to be run and debugged using the Visual Studios internal development web server and SQL Server Express, basically by pressing F5 after checking out the code.

Initial Requirements

In agile fashion the project will start with some initial requirements, additional requirements can be added as the project evolves.

  • A default or index page showing recent posts in reverse chronological order
  • A post page, using the same URI routing as BlogEngine.NET
  • A Metaweblog API implementation to support Windows Livewriter for publishing and managing content on the weblog

So that's it for now, hopefully we can knock this first iteration together pretty quickly.

Tasks

I don't want to get to far into fine grained tasks as I don't have to estimate the project time or cost, but I do want to cover the basic tasks as it does give an indication of what I expect will need to be done for this phase.

  • Create the database
  • Create the LINQ to SQL classes
  • Create a Data Layer and a Data Layer Interface
  • Write some Data Layer Tests
  • Create a Model (tests?)
  • Create a Controller
  • Write some Controller Tests
  • Setup some routes
  • Create the index view
  • Create the post view
  • Implement the Metaweblog API

Lets Rock'n'Roll

Hopefully I'll be posting the learning from phase one and the goals of phase two next week.


Tags: ,
Categories:
Comments (4)

#.think.in infoDose #7 (10th Nov - 15th Nov)

November 17, 2008 09:23 by brodie

Management/Process

Architecture

ASP.NET

jQuery

WCF

MEF - Managed Extensibility Framework

Silverlight

UI Design

Testing/Debugging

Singularity Watch

Other


Tags:
Categories:
Comments (3)