Brian Hartsock's Blog

Tag: C#

Using Extension Methods to clean up Mocks (MoQ)

by bhartsock on Sep.01, 2009, under Uncategorized

Mock’s can quickly become an ugly beast. They require lots of complex setup and verification. I have had good luck with using extension methods to simplify the complexity.

Assume we have the following code to implement our data layer on top of some ReST API.

public interface IWebClient
{
    string DownloadString(string url);
    string UploadValues(string method, string address, NameValueCollection data);
}
public class WebClientWrapper : IWebClient
{
    private WebClient client;
 
    public WebClientWrapper()
    {
        client = new WebClient();
    }
 
    public string DownloadString(string url)
    {
        return client.DownloadString(url);
    }
 
    public string UploadValues(string method, string address, NameValueCollection data)
    {
        return Encoding.UTF8.GetString(client.UploadValues(address, method, data));
    }
}

In the business/domain layer, we have a class that uses IWebClient to get some information from the API.

public class BusinessObject
{
    IWebClient client;
 
    public BusinessObject(IWebClient _client)
    {
        client = _client;
    }
    public XmlDocument FindCustomer(string search)
    {
        var result = client.DownloadString(
            string.Format("http://someApi/customers?search={0}",
                HttpUtility.UrlEncode(search))
            );
 
        return BuildXml(result);
    }
    public XmlDocument FindCustomer(char startsWith)
    {
        var result = client.DownloadString(
            string.Format("http://someApi/customers?startsWith={0}",
                HttpUtility.UrlEncode(startsWith.ToString()))
            );
 
        return BuildXml(result);
    }
    private XmlDocument BuildXml(string result)
    {
        var doc = new XmlDocument();
        doc.LoadXml(result);
        return doc;
    }
}

How do we go about testing this? My first attempt would look something like the following, relying heavily on MoQ.

[TestFixture]
public class BusinessObjectTests
{
    string resultXml = "<xml><customer></customer></xml>";
    Mock<IWebClient> client;
    BusinessObject bo;
 
    [SetUp]
    public void Setup()
    {
        client = new Mock<IWebClient>(MockBehavior.Strict);
        bo = new BusinessObject(client.Object);
    }
 
    [Test]
    public void Find_customer_using_search()
    {
        client.Setup(s => s.DownloadString("http://someApi/customers?search=searchVal"))
            .Returns(resultXml)
            .AtMostOnce();
 
        bo.FindCustomer("searchVal");
 
        client.VerifyAll();
    }
 
    [Test]
    public void Find_customer_using_filter()
    {
        client.Setup(s => s.DownloadString("http://someApi/customers?startsWith=a"))
            .Returns(resultXml)
            .AtMostOnce();
 
        bo.FindCustomer('a');
 
        client.VerifyAll();
    }
}

But I don’t like this. It is very verbose, and doesn’t resuse functionality very well. Morever, in real world examples, there would probably be many more functions with very similar setup and verification steps. How can we refactor this to make it better?

public static class ClientMockExtensions
{
    public static void VerifyGetContainedParmeter(this Mock<IWebClient> client, string name, string value)
    {
        client.Verify(c => c.DownloadString(
          It.Is<string>(s => s.IndexOf(name + "=" + value) > s.IndexOf("?"))));
    }
}
[TestFixture]
public class BusinessObjectTests
{
    string resultXml = "<xml><customer></customer></xml>";
    Mock<IWebClient> client;
    BusinessObject bo;
 
    [SetUp]
    public void Setup()
    {
        client = new Mock<IWebClient>(MockBehavior.Strict);
        bo = new BusinessObject(client.Object);
 
        client.Setup(s => s.DownloadString(
            It.Is<string>(str => str.StartsWith("http://someApi/customers"))))
            .Returns(resultXml)
            .AtMostOnce();
    }
 
    [Test]
    public void Find_customer_using_search()
    {
        bo.FindCustomer("searchVal");
 
        client.VerifyGetContainedParmeter("search", "searchVal");
        client.VerifyAll();
    }
 
    [Test]
    public void Find_customer_using_filter()
    {
        bo.FindCustomer('a');
 
        client.VerifyGetContainedParmeter("startsWith", "a");
        client.VerifyAll();
    }

In the example, I use extension methods to reuse verification steps, which also makes the tests much cleaner. Too many times developers stay away from complex verification steps in favor of complex setups. I think it is cleaner to do a more generic setup, and then use verify to get down to the specifics of what was done.

Post to Twitter Post to Digg Post to Facebook Post to Reddit

Leave a Comment :, , , more...

Speaking at Richmond Code Camp on NHibernate

by bhartsock on Aug.31, 2009, under Uncategorized

On October 3rd, I encourage anyone who wants to learn about NHibernate to come to Richmond Code Camp. I will be giving a 100 level talk describing how to get started using it, and what it really is.

My initial idea is to create a fairly simple ASP.NET MVC application without persistence (use in memory Lists). And, in an hour, make it 100% persisted with transactions, lazy loading, etc. I am a little concerned it will be hard to teach NHibernate and get it done in an hour, but I am going to go for it. My goal is to touch on session factories, sessions, simple XML mapping, attribute mapping, inheritance relationships, associative relationships, criteria queries, HQL queries, and lazy loading. If I get through all that, I’ll throw in some custom types and maybe some fluent NHibernate since I have never used it but have wanted a reason to.

Any suggestions on things to show or things not to show?

Post to Twitter Post to Digg Post to Facebook Post to Reddit

2 Comments :, , , , more...

PSDefaultVariablizer revisted

by bhartsock on Aug.31, 2009, under Uncategorized

A couple of days ago, I had a random post about PSDefaultVariablizer because I thought the name was funny. Well, I did some pretty hardcore refactoring of the class, and am pretty happy with the outcome. Overall, I think it is 100x better. Check it out.

public class PSDefaultVariablizer<T> where T: class
{
    T innerValue;
    IList<Func<T>> defaultValues;
 
    public PSDefaultVariablizer(params Func<T>[] _defaultValues)
    {
        defaultValues = _defaultValues.ToList();
        defaultValues.Insert(0, () => this.innerValue);
    }
 
    public T Value
    {
        get
        {
            return defaultValues.Select(v => v.Invoke())
                .Where(v => v != null)
                .FirstOrDefault();
        }
        set
        {
            innerValue = value;
        }
    }
}
 
//I am using it in a cmdlet similar to this
[Cmdlet("Some", "Command")]
public class SomeCommand : PSCmdlet
{
    private PSDefaultVariablizer<string> someParam;
 
    public SomeCommand ()
    {
        someParam = new PSDefaultVariablizer<string>(() => (string)this.SessionState.PSVariable.GetValue("SomeParam", null));
    }
 
    [Parameter()]
    public string SomeParam
    {
        get
        {
            return someParam.Value;
        }
        set
        {
            someParam.Value = value;
        }
    }
}

Thought it was cool to use Lamba’s to eliminate an entire dependency. I should really call this DefaultVariablizer because it has no dependency to Powershell.

Post to Twitter Post to Digg Post to Facebook Post to Reddit

Leave a Comment :, , more...

PSDefaultVariablizer – I didn’t know what else to name it!

by bhartsock on Aug.25, 2009, under Uncategorized

public class PSDefaultVariablizer<T> where T: class
{
    string variableName;
    T innerValue;
    PSCmdlet cmdlet;
 
    public PSDefaultVariablizer(string _variableName, PSCmdlet _cmdlet)
        : this(_variableName, null, _cmdlet) { }
 
    public PSDefaultVariablizer(string _variableName, T _innerValue, PSCmdlet _cmdlet)
    {
        variableName = _variableName;
        innerValue = _innerValue;
        cmdlet = _cmdlet;
    }
 
    public T Value
    {
        get
        {
            if(innerValue != null)
            {
                return innerValue;
            }
            else
            {
                return (T)cmdlet.SessionState.PSVariable.GetValue(variableName, null);
            }
        }
        set
        {
            innerValue = value;
        }
    }
}

Here is the use case for the class. You have a parameter that a user can input, otherwise it attempts to use a value of a variable in the same scope (think how $ErrorActionPreference works). This class allows you to very simply reuse that functionality.

[Cmdlet("Some", "Command")]
public class SomeCommand : PSCmdlet
{
    private PSDefaultVariablizer<string> someParam;
 
    public SomeCommand ()
    {
        someParam = new PSDefaultVariablizer<string>("SomeParam", this);
    }
 
    [Parameter()]
    public string SomeParam
    {
        get
        {
            return someParam.Value;
        }
        set
        {
            someParam.Value = value;
        }
    }
}

And you would use it from Powershell with the following.

Some-Command -SomeParam 'hello'
#or
$SomeParam = 'hello'
Some-Command

Pretty simple really. I just posted it because I thought the name was hilarious, but I didn’t really know what else to call it.

Let me know if anyone knows of an easier way to this. Unfortunately, there aren’t too many people I can talk to about SnapIn development :)

Post to Twitter Post to Digg Post to Facebook Post to Reddit

Leave a Comment :, , more...

A night of firsts: VS2010, Dynamics, Python

by bhartsock on Jul.19, 2009, under Uncategorized

Tonight, I installed Visual Studio 2010 beta 1 for the first time. I know I am late to the game, but I had to give it a whirl since I found some free time this afternoon. One feature of .NET 4.0 I wanted to try out was the dynamic keyword with Python scripting. So, here is my first hello world program using dynamic, with the help of this walk-through.

class HelloWorldDemo:
 
    def run(self):
        return "hello world"

Here is the C# code needed to run it. Yes, I used WPF as my driver, but don’t worry about that.

...
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
 
namespace WpfWithPython
{
    public partial class Window1 : Window
    {
        ScriptRuntime py;
        public Window1()
        {
            InitializeComponent();
            py = Python.CreateRuntime();
        }
 
        private void MyBtn_Click(object sender, RoutedEventArgs e)
        {
            //Instantiate an instance of this file?!  Yes, it is weird at first.  
            // All the methods and classes in the file will be members.
            dynamic demo = py.UseFile("HelloWorldDemo.py");
 
            //This is the tricky step.  To create a new object, call it like a member...
            // I think
            dynamic instance = demo.HelloWorldDemo();
            MyText.Text = instance.run();
        }
    }
}

It took me a while to get this little bit of code working unfortunately. If you read the comments, you can see where some of my confusion was found. Overall, it is pretty awesome. I loved LINQ and I am already loving dynamic. There is something new to learn everyday. Maybe F# next…

Unfortunately, I have to say that VS2010, while pretty, is slower than 2008. And, IronPython took nearly 2 or 3 minutes to run some sample code it provided, which is crazy. If the performance problems can be overcome, then I see myself learning more Python and Ruby.

Post to Twitter Post to Digg Post to Facebook Post to Reddit

3 Comments :, , , , , more...