Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious
 

RhinoMocks new Arrange, Act, Assert does not seem to work under MSTest....odd

-- UPDATE See text in red below --

Ok, I am in NO way trying to say that this is either Rhino's issue or MSTest.  I am simply blogging this with the intent that someone can shed some insight as to what may be going on.  Although, since I know that the AAA logic of Rhino works with the EXACT same code under NUnit i have to believe it has something to do with the MSTest works.

So here is my propblem:

I have a test where i want to mock out and set an expectation on a repository.  When I tried the code via the AAA syntax my expectation would only return a null.  When I changed to use Record/Playback everything worked well.  Odd.

Here is the syntax for AAA (non-working)

var mockRepository = new MockRepository();
var mockStatusCheckRepository = mockRepository.DynamicMock();

mockStatusCheckRepository.Expect( x => x.GetCustomerAuditInformation( "", "" ) ).IgnoreArguments().Return( new CustomerAuditInformation { NeedsInitialDataCreated = true } ).Repeat.Once();
var information = mockStatusCheckRepository.GetCustomerAuditInformation( "", "" );
// Returns null

I was able to get this working by NOT using the instance of MockRepoistory, instead using the Static Methods.  Belows Code works

var mockStatusCheckRepository = MockRepository.GenerateMock();

mockStatusCheckRepository.Expect( x => x.GetCustomerAuditInformation( "", "" ) ).IgnoreArguments().Return( new CustomerAuditInformation { NeedsInitialDataCreated = true } ).Repeat.Once();

var information = mockStatusCheckRepository.GetCustomerAuditInformation( "", "" )

So, this may just be a case of me not fully understanding the new AAA syntax and how to use it, but I know that using the instance stuff works under NUnit... odd


Here is the syntax for the Record/Playback (working) - Can use the AAA syntax above as well

var mockRepository = new MockRepository();
var mockStatusCheckRepository = mockRepository.DynamicMock();

using ( mockRepository.Record() )
{
    mockStatusCheckRepository.Expect( x => x.GetCustomerAuditInformation( "", "" ) ).IgnoreArguments().Return( new CustomerAuditInformation { NeedsInitialDataCreated = true } ).Repeat.Once();

}

using ( mockRepository.Playback() )
{
    var information = mockStatusCheckRepository.GetCustomerAuditInformation( "", "" );
}

Cany anyone shed some light on this?  Is there a way around this?

Till next time,

[----- Remember to check out DimeCasts.Net -----]

MSTest, why I hate you.... You cause me too much friction

Yesterday I spent 4+ hours trying to tackle a bug that should not have been a bug in the first place, and the culprit was MSTest.  Please keep in mind that I have never really used MSTest in any real form.  I am a NUnit guy through and through.

Here is some background on what I was trying to do (keep in mind, I have done this numerous times in the past).  I was setting up an application that was going to use the StructureMap Ioc/DI (Version 2.4.9 -- aka 2.5) container.  Because I do not mind using the attributres and StructureMap.config files this was the way I was going to do all the wiring for my container. 

During the testing (via MSTest) of this code, I immediatly ran into an issue with the .config file not being found at runtime.  Now this was odd to me as I could see that the .config file was being copied to the output directly like it should be.  I spent the next 20-30 minutes ensuring that all my code was correct and that the config file was indeed in the right place.

It was not till I was stepping though the current directory was not my /bin folder, but rather \TestResults\whitt010_CM4NRG1 2008-07-22 16_18_25\out (if you have ever used MSTest you will understand the folder naming convetion).  I found this to be very, very odd.  I did a little digging and realized that for each test run MSTest will create a new folder to run all the tests in (why, I have now figgen clue).  But because my .config file was not a 'normal' file in the eye of MSTest it was not being copied.  Well, my good buddy Steven Andrews was nice enought to help me figure out how to copy the .config file to the correct output folder (post on that forthcoming).  Well, I thought this would solve my issue, but it did not.

Now that I have the .config in the correct test folder (again, not in the bin like ALL the other testing frameworks..why does MS always have to be different) I thought I would be golden.  However, I was still not able to get this working.  After another hour or two of beating my head against the wall, and of bothering both Chad Myers and Jeremy Miller (father of StructureMap).  I finally realized what was going on.  When MSTest runs, it sets the current working directory to c:\<InstallBase>\Microsoft Visual Studio 9.0\Common7\IDE because that is where MSTest runs.  Because of this StructureMap was having issues finding the .config file (before you jump to SM as being the issue, think again.  I have done this before both with NUnit and MBUnit and both work fine).

Alas after 4+ hours into my journey I threw in the towel.  I decided that using the StructureMap.config file method with MSTest was just too much friction.  So again with the help of Jeremy and Chad (do not know who was actually typing in the IM window as they were both there) I decided to solve the problem another way.

Here is what I did to get everything working:

  1. Download and use StructureMap 2.4.9 (aka 2.5)
  2. No-longer used the StructureMap.config file.... bye bye my friend
  3. Setup StructureMap to read my config info from my app.config
    1. This involves moving my config info to the app.config
    2. Telling StructureMap how to read from the app.config (blog post on this soon)
  4. Swore over and over again at the pain that MSTest caused me.

In intend to create a few more detaild posts on this over the next few days and will links to them here.

Hope this helps someone.

Till next time,

[----- Remember to check out DimeCasts.Net -----]

[ANN] New guest Author on Dimecasts.net - Justin Etheredge

Today we have another guest author on Dimecasts.net.  In this series Justin will be teaching all of us how to use the Ninject IoC container.

Justin's first episode can be found here, and keep a look out for more future episodes.

Till next time,

Building a WPF Application: Part 1

I actually meant to say in my last post that I had investigated the API options for FriendFeed and they have a C# wrapper already available here. It's packaged up in a single download with its Python and PHP counterparts.  Unfortunately, it has compilation errors. I fixed the errors and then I let ReSharper (R#) have its way with it [R#: Ctrl+Alt+Shift+F]. Yes, I do understand that the Code Cleanup feature of R# can be a nuclear bomb of churn for diffing your source, but egads I do love it so.

FriendFeed project in the solution explorerI also broke out the FriendFeed classes into separate files [R#: F6].

Hmm, I just decided that I'll notate R# and VisualStudio keyboard shortcuts like this [app:shortcut]. Is there already a convention for that out there?

I also decided to keep the FriendFeed code in a separate assembly. I don't always advocate assembly proliferation, but it made sense in this case. I created a project called FriendFeed and moved all their classes there.  I also preserved their namespace, FriendFeed, as well. (I'm getting tired of typing "FriendFeed".)

At this point, I just wanted to get a feel for the API. So I read over what appeared to be the significant classes, and I used a couple of tests to see how it really works. Simple enough, instantiate the client and call FetchHomeFeed().

Building in Seams

I picked up the term seam from Ayende in this post. You can think of a seam as a natural boundary in an application. It's a place where you easily extend or modify an application. It's a little bit like a Bounded Context, but just a little. I used to try to coerce my design into the metaphor of layers, but seams are a more natural concept. You might also think of them as a way of describing componentized architecture.

Consider the example of a desktop computer: you have a motherboard, CPU, memory, video card, etc. All of the components are required for the computer to function, but you can replace any one of them. You can extend the functionality of the computer by adding more hardware. Some things might be tightly coupled, like those wretched integrated video cards. But you don't think of these components as layers. This is a flexible way to architect your application.

Seams are a standard consideration for me when it comes to designing an application. Yes, you can go crazy with it, you can go crazy with anything. In the case of ChumChase, I don't want to be tightly coupled to the official API. I have a few reasons right now: [a] the official API might change. [b] I might want to implement my own API against their web services just for kicks [c] it's a good excuse to demonstrate the technique. I'm going to hide the FriendFeed API behind a repository. The IFeedRepository interface will be a seam in my application.

MVP

I mentioned before that I'm going to use Model-View-Presenter. This pattern is similar to MVC, and like barbeque sauce, everyone has their own flavor. In my case, a presenter is a class that represents the behavior of the UI, and possibly some state. It is ignorant of how the UI visually appears. The view will be a user control, window, page, tab item, etc. We'll use data binding to glue the two together. The ignorance of the presenter about the view is important because it helps us to isolate the presenter in our unit tests.

TDD

It's sometimes hard to decide where to start writing to tests. I tend to write tests that reflect the behaviors of the user interacting with the application. This is as opposed to testing how the application might interact with a data source, or some other more internal function of the application. This approach of working from the outside in helps prevent me from making too many assumptions about the internals.  The negative is that I have to provide mocks or stubs for the dependencies that I haven't written yet.

My core story, that is the basic behavior that I'm interested in, is for the application to fetch my home feed. I'll place this feature on a class called HomePresenter. HomePresenter might end up being my only presenter, I don't know yet. It common though for applications to have several presenters. We'll talk later about how to logically organize presenters.

Let's look at a test:

[TestFixture]
public class The_presenter_for_the_home_feed : TestFixtureBase
{
    private HomePresenter _presenter;
    private IFeedRepository _feedRepository;

    protected override void given_the_context_of()
    {
        _feedRepository = Mocks.StrictMock<IFeedRepository>();
        _presenter = new HomePresenter(_feedRepository);
    }

    [Test]
    public void can_refresh_the_home_feed()
    {
        using (Record)
        {
            Expect.Call(_feedRepository.FetchHomeFeed())
                .Return(new List<Entry>());
        }

        using (Playback)
        {
            _presenter.RefreshHomeFeed();
        }
    }
}

First, my TestFixtureBase is just an abstract class to reduce clutter. The Mocks, Record, and Playback properties all exist on it and they are really just pass-throughs to Rhino.Mocks. Likewise, I have a setup method in TestFixtureBase that calls given_the_context_of() before each test is executed. It's meant to reset the system-under-test (SUT) into a consistent and pristine state.

Notice that I named my class and method such that they read as a specification for the behavior I'm testing: The presenter for the home feed can refresh the home feed. I'm not sure that I like saying "presenter" in the specification. If I was working with non-technical users, that wouldn't make sense to them. I could replace it with "UI" or "interface" or "screen" perhaps.

The test has two blocks or phases: record and playback. This is generally a big stumbling block for people. I know when I first encountered it I was thoroughly confused. The record phase is where I tell the test what I'm expecting to happen during the playback phase.  The record phase plays the same roles as asserts.

The function we are really testing here is:

_presenter.RefreshHomeFeed();

Since there is not a state that I can verify after calling RefreshHomeFeed(), I am checking to make sure that it's doing what I expect it to do. That is, I expect it to get a list of entries from a repository of feeds.

The Expect.Call().Return() is Rhino.Mocks syntax that allows me to say: I expect my SUT to execute _feedRepository.FetchHomeFeed() and I expect that to return a List<Entry> instance. Right now Entry is just an empty class, but conceptually it represents a single item in the feed. You should also note that the relationship between my presenter and the repository is established in given_the_context_of().

Yes, this is a simple test, but writing this test helped me to shake out what I needed.  Unfortunately, the test as it stands here does not reflect the process of writing it.  I wrote some things, decided they didn't look right, changed them a bit and so on. It probably took me 10 minutes or so before I settled on what you see.

Moving on to the next test. This is in the same class, so you can read it as: The presenter for the home feed notifies the UI when the home feed is refreshed.

[Test]
public void notifies_the_UI_when_the_home_feed_is_refreshed()
{
    var property_has_changed = false;

    _presenter.PropertyChanged +=
        (s, e) => { property_has_changed = (e.PropertyName == "HomeFeed"); };

    _presenter.RefreshHomeFeed();

    Assert.That(property_has_changed);
}

I want to verify that when I call _presenter.RefreshHomeFeed() a change notification is raised for the HomeFeed property. This means my presenter needs a HomeFeed property. I have a boolean flag that helps me track the state and I'm using an inline delegate to set my flag when the property is changed. (There's actually a flaw in this test that we'll examine later, can you see it?) 

I don't like strings though. If I happen to change the name of the HomeFeed property and forget to change the string in the test, I've broken my test. Of course, I'll notice as soon as I run the tests, but it would sure be nice to eliminate the string. So I wrote this extension method for PropertyChangedEventArgs:

public static bool HasChanged<T>(this PropertyChangedEventArgs args, Expression<Func<T>> property)
{
    var expression = (MemberExpression)property.Body;
    return expression.Member.Name == args.PropertyName;
}

Now I can change my test to the following and eliminate the string:

[Test]
public void notifies_the_UI_when_the_home_feed_is_refreshed()
{
    var property_has_changed = false;

    _presenter.PropertyChanged +=
        (s, e) => { property_has_changed = e.HasChanged(() => _presenter.HomeFeed); };

    _presenter.RefreshHomeFeed();

    Assert.That(property_has_changed);
}

Of course, in between these tests I was writing code to make them pass. (Red -> Green -> Refactor, right?) Here's what my presenter class looked liked afterwards:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using ChumChase.Extensions;

namespace ChumChase.Presenters
{
    public class HomePresenter : INotifyPropertyChanged
    {
        private readonly IFeedRepository _feedRepository;
        private IList<Entry> _homeFeed;

        public HomePresenter(IFeedRepository feedRepository)
        {
            _feedRepository = feedRepository;
        }

        public IList<Entry> HomeFeed
        {
            get { return _homeFeed; }
            private set
            {
                _homeFeed = value;
                OnPropertyChanged( ()=> HomeFeed);
            }
        }

        public void RefreshHomeFeed()
        {
            HomeFeed = _feedRepository.FetchHomeFeed();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged<T>(Expression<Func<T>> property)
        {
            if (PropertyChanged != null) PropertyChanged(this, property.CreateChangeEventArgs());
        }
    }
}

The source is now available here. More to come!

Design Patterns in Ruby - book review

I have a friend that is very much into Design Patterns and wanted to learn Ruby with a more applied perspective of the language.

I went the exact opposite direction. I know a little bit of Ruby already and I wanted to improve my limited patterns knowledge.

What we had in common is that we both picked up Design Patterns in Ruby by Russ Olsen. The title can be a little deceiving in that you might think it assumes Ruby knowledge, but no, it actually covers the Ruby language at a level that doesn't bore the reader with programming basics. The book assumes you know how to program already but you're new to Ruby.

After an introductory chapter about Ruby basics, the book delves into Design Patterns, their formal definitions, how they look like in Ruby, how to leverage Ruby features to tweak the patterns, and examples of the pattern being used in examples extracted from the Ruby class library or popular components (gems). As the examples and tweaks are being presented, any new Rubyism being applied is explained.

I found this book to be a great way to learn more about the Design Patterns and the proper way to implement them in Ruby. I also learned a little more Ruby and some language features that I did not know how to use yet.

[ANN] New guest author on DimeCasts.net

This posting is a few days late, sorry Kirstin.  But last week DimeCasts got another great guest author to submit content.

Kirstin Juhl (soon to be TFS Queen) submitted the first of a long line of TFS screencasts.  Her first episode can be found here, and keep a watch out for future episodes by her.

Till next time,

Referencing 2.0 Web Services (asmx) in Visual Studio 2008

Recently I needed to add a reference to a classic (.Net 2.0) web service inside a new project that was being created via Visual Studio 2008. 

Now, I have not done a lot of work with WebServices in the past 6-9 months, but thought it would be cake.  Please keep in mind, the service I wanted to connect to was NOT a WCF Service, it was a standard ASMX service.

Below is what I thought would work, but did not

  1. Attempt to Add A Service ReferenceAddAServiceReference
  2. Choose Services in Solution (my Project is in the same solution file).
    ServicesInSolution 
  3. View the generated service implementation.
    IncorrectGeneratedService
  4. WCF Style code implementation
    WCFStyleImplementation 

What you will notice from step 4 is that the way you go about implementing this service is in the WCF style.  This is not what I was looking for.  I was wanting to reference this like all the other code in our projects.

Below is what DID work

  1. Attempt to Add A Service ReferenceAddAServiceReference
  2. Need to click the Advanced button
    ClickAdvancedButton 
  3. Need to add the service as a Web Reference
    ClickAddWebReference 
  4. Finally need to search for and find your web service
     AddWebReference
  5. Lastly, if you have done everything correctly, you should see the following.
    CorrectlyGeneratedService

Now I know that the preferred service type is now WCF, but come-on not everyone is using WCF just yet.  Adding a traditional web service reference is way too much friction.  Why is not possible to add a reference from the solution explorer?  Really can anyone answer me that.

Till next time,

[----- Remember to check out DimeCasts.Net -----]

More Posts Next page »

Red-Gate!


What's New

Who Is Online

The Devlicio.us Crew

Derik Whittaker
310 Posts | 1,127 Comments | 292 Trackbacks
Christopher Bennage
48 Posts | 159 Comments | 68 Trackbacks
Sergio Pereira
39 Posts | 104 Comments | 71 Trackbacks
Casey Charlton - Insane World
27 Posts | 79 Comments | 48 Trackbacks
ViNull, Off the Record
12 Posts | 7 Comments | 14 Trackbacks
Billy McCafferty
67 Posts | 547 Comments | 85 Trackbacks
Lazy Developer
49 Posts | 117 Comments | 26 Trackbacks
.NET & Funky Fresh
41 Posts | 168 Comments | 177 Trackbacks
Mike Nichols - Son Of Nun Technology
25 Posts | 95 Comments | 22 Trackbacks
Javier Lozano
0 Posts | 0 Comments | 0 Trackbacks
Jeff Perrin - Sexier Than You Are
13 Posts | 80 Comments | 6 Trackbacks
The Bolla Blog
11 Posts | 55 Comments | 6 Trackbacks
Alan Northam
13 Posts | 59 Comments | 15 Trackbacks
Brendan Tompkins
15 Posts | 107 Comments | 18 Trackbacks
Stephen Wright
12 Posts | 50 Comments | 9 Trackbacks

Devlicio.us Alumni

Marcin Hoppe
8 Posts | 14 Comments | 0 Trackbacks
Michal Grzegorzewski
8 Posts | 20 Comments | 1 Trackbacks
Expanding the .NET blogosphere
7 Posts | 28 Comments | 5 Trackbacks
Lou Haskett
2 Posts | 11 Comments | 0 Trackbacks
Ken Gabe
1 Posts | 1 Comments | 0 Trackbacks
The Perpetual n00b
8 Posts | 35 Comments | 2 Trackbacks
Daniel Arak
1 Posts | 51 Comments | 0 Trackbacks
IDOTNET - Further along the road...
5 Posts | 1 Comments | 1 Trackbacks