Archive

Archive for the ‘Development’ Category

GridViewCommandEventArgs.CommandName problem in Visual Studio.Net Cassini

August 4th, 2008 Scott Lilly Comments off

I ran into an extremely frustrating problem with GridViewCommandEventArgs.CommandName this weekend.

While working with the OnRowCommand event on a GridView object in ASP.Net, the code in my code-behind page was not doing what it should have for the asp:ButtonField that I had in the grid.  So, I set a breakpoint and watched what was happening.  When the code got to the line “if ( e.CommandName == “RaiseStoryInPriority” )”, it never executed the code within the “if” statement, even though hovering over “e.CommandName” showed that the value was equal. After trying several different things (and beating my head against the wall for far too long) I tried running the code through IIS, instead of the Cassini web server that runs your code when you press F5 in Visual Studio.Net. The code worked perfectly in IIS.

I also ran into a different problem with Cassini a while back. I was using a cache object and tried to clear out a value by assigning “null” to it. That worked in Cassini, but not in IIS. In IIS, I had to use the Remove() method.

So, if you see something that looks like it should be working, but isn’t, it might be worthwhile to run it your application through IIS and see if you still have the problem. That might save you from an hour of frustration.

Categories: ASP.Net, C#, Development Tags:

Using Rhino Mocks with Void (or ‘Sub’) Methods

July 22nd, 2008 Scott Lilly Comments off

I ran into a bit of trouble the other day when I was writing a test with Rhino Mocks.  It took a while to find the solution, so I figured I’d post it here for anyone else looking to do the same thing.

The problem I had was trying use a mock object for my data access layer, and calling a void method on the class.  There are thousands of examples of how to mock a method call that returns a value, but it took a while to find out how to handle a method call that doesn’t return anything.  In my test below, if the method returned something, I’d use code like this:

using ( mockery.Record() )
{
   Expect.Call( dal.ExecuteQuery( null ) ).IgnoreArguments().Return( results );
}

For a void method (or ‘Sub’, instead of ‘Function’, for the VB.Net developers), you need to set up a delegate instead. See the line that calls “ExecuteNonQuery” for an example.

[Test]
public void CreateNewUserStory()
{
   MockRepository mockery = new MockRepository();
   IDataAccessor dal = mockery.CreateMock<idataaccessor>();

   IUserStoryControl screen = mockery.Stub<iuserstorycontrol>();
   UserStoryController controller = new UserStoryController( dal );

   screen.StoryTitle = “Test title”;
   screen.Description = “Test description”;

   using ( mockery.Record() )
   {
      Expect.Call( delegate { dal.ExecuteNonQuery( null ); } ).IgnoreArguments();
   }

   using ( mockery.Playback() )
   {
      controller.CreateNewUserStory( screen );
   }

   Assert.AreEqual( “”, screen.StoryTitle );
   Assert.AreEqual( “”, screen.Description );
}

Categories: Agile, Development, Mock Objects, Testing Tags:

Putting interfaces in their own project(s)

July 13th, 2008 Scott Lilly Comments off

When I started using test-driven development and the model-view-controller pattern, I noticed a change in the way I broke up the projects in a typical solution.  Well, I noticed several changes, but the one I’m going to talk about now is how the user stories started to become the API of my business logic.  Because of the separation of the UI and the business logic that’s created by using the MVC pattern, my user interface has become a consumer of my business logic through this API.  Writing code this way gives me the flexibility to use the same logic with a completely different UI.

That may not sound like the kind of things that comes in handy very often; however, it’s making my life much easier for the latest project I’m working on.  I’m working on an ASP.Net website, but I also plan on creating a Visual Studio plug-in, so developers can access the website features without needing to leave their editor and open a new browser.  I may also end up writing a system tray tool that works the same way.  I haven’t decided if the plug-in will communicate with my application by a web service, remoting, or WCF.  But whatever method it uses, I’ll just end up writing a small bit of wrapper code in it to communicate with my business logic through the user story API.

Normally, my solution file will start out with four projects in it.  They are:

- MyLibrary (containing things like my data access layer)
- Domain (the application’s business logic)
- Application (the UI project)
- TestDomain (unit tests for the Domain project)

The MyLibrary and Domain projects each contain an Interfaces folder, and the files within them are in the MyLibrary.Interfaces and Domain.Interfaces namespaces.  The Application project has references to both the MyLibrary and Domain projects.  However, since I’m going to have additional projects that will be passing objects of the interface types into a web service (for this example), They will either need to include the complete MyLibrary and Domain assemblies, or I’ll need to move the interfaces into their own assemblies.  In order to keep the installations for the new projects small, I’ll move the interfaces into their own projects.  So, the solution will now look something like this:

- MyLibrary (containing things like my data access layer)
- MyLibrary.Interfaces (the public interfaces used within MyLibrary)
- Domain (the application’s business logic)
- Domain.Interfaces (the public interfaces used within Domain)
- Application (the UI project)
- Notifier (system tray notifier project)
- Plugin (Visual studio plugin project)
- WebService (used by the Notifier and Plugin projects to communicate with the Domain layer)
- TestDomain (unit tests for the Domain project)

The Application and TestDomain projects (along with the new Notifier and WebService projects) will now need references to the new *.Interfaces projects.  However, the Notifier and Plugin will only need to have the small *.Interfaces assemblies included for the installation.

Categories: Development Tags: