Showing posts with label tutorials. Show all posts
Showing posts with label tutorials. Show all posts

Wednesday, July 16, 2008

Mocking asynchronous actions with Typemock Isolator

Here is an answer to a question that keeps popping up every once in a while: how do you stub out asynchronous actions in your class under test? Assuming that you can't\won't change the code and refactor it (usual case in most legacy systems), here is a class with an async action you'd like to stub:

 public class ClassWithAsync

    {

        public void Do(int input,Action<int> resultCallback)

        {

            ThreadPool.QueueUserWorkItem(state =>

                                            {

                                                Thread.Sleep(1000*3);

                                                resultCallback(input*2);

                                            });

        }

    }

 

The ThreadPool.QueueUserWorkItem will invoke our callback asynchronously. Here are two versions of the same test that you can write. The first one is the strogly typed version, which will required the pro or enterprise versions of Typemock Isolator. The second one will work with the free community edition of Typemock.

 

   10 [Test]

   11         public void AsyncMocking_NaturalMocks()

   12         {

   13             bool wasCalled = false;

   14             int passedResult = 0;

   15 

   16             ClassWithAsync target = RecorderManager.CreateMockedObject<ClassWithAsync>();

   17 

   18             using (RecordExpectations rec = new RecordExpectations())

   19             {

   20                 target.Do(0,null);

   21                 rec.Return(new DynamicReturnValue(delegate(object[] parameters, object context)

   22                                                       {

   23                                                           Action<int> theUserCallback =

   24                                                               parameters[1] as Action<int>;

   25                                                           theUserCallback(11);

   26                                                           return null;

   27 

   28                                                       }));

   29             }

   30 

   31             target.Do(5, delegate(int result)

   32             {

   33                 passedResult = result;

   34                 wasCalled = true;

   35             });

   36             Assert.IsTrue(wasCalled);

   37             Assert.AreEqual(11, passedResult);

   38 

   39         }

The way this test works:

in line 16: we create a mocked version of the class we'd like to stub out. then we start a recording session with Isolator where all method calls are recorded. in line 20 we invoke the method for recording purposes. essentially saying "a call to target.do()" will be made later.  any parameters we pass in that line are ignored.

rec.Return tells the recorder what to return or execute when the method is actually called. in this case we are create something called a DynamicReturnValue which allows us to send in our own delegate that does whatever we want. in this case we are taking in the parameters that were sent to this method (the second one is the user's delegate).

when the recording block has ended (the end of the using block) we simply invoke the class. this is code that will usually not be in a test, but will be in the production code that we invoke. we are just simulating what the production code might do. we pass in our own delegate as the callback to the method, and in it we just set some variables that we will assert against.  (We pass in 11 to show that we control the output. the original class would have returned 10.

Here is the community edition version of this test: no record\replay support but should work just the same:

 

   13 [Test]

   14         public void AsyncMocking_ReflectiveMocks()

   15         {

   16             bool wasCalled = false;

   17             int passedResult = 0;

   18 

   19             MockObject<ClassWithAsync> mockObject = MockManager.MockObject<ClassWithAsync>();

   20             mockObject.ExpectAndReturn("Do",

                                         new DynamicReturnValue(delegate(object[] parameters, object context)

   21                                                     {

   22                                                      Action<int> theUserCallback =

   23                                                      parameters[1] as Action<int>;

   24                                                      theUserCallback(((int)parameters[0]) *2 +1);

   25                                                      return null;

   26 

   27                                                     }));

   28 

   29             ClassWithAsync mockedClass = mockObject.MockedInstance;

   30             mockedClass.Do(5, delegate(int result)

   31                                   {

   32                                       passedResult = result;

   33                                       wasCalled = true;

   34                                   });

   35             Assert.IsTrue(wasCalled);

   36             Assert.AreEqual(11,passedResult);

   37 

   38         }

 

Any questions?

Monday, July 14, 2008

Racing Philosophers

This post describes a known deadlock problem and how Typemock Racer can be used to discover deadlocks in .NET code.

You can read more about Typemock Racer at ISerializable Blog.

 

Overview

The well known computer science problem called Dining philosophers was invented by E. W. Dijkstra:image

A number of philosophers (usually five but it could work with any number larger than two) sitting around a table thinking about philosophical problems.  Each philosopher has a bowl of rice and two chopsticks he can use to eat it.

Every now and then a philosopher gets hungry and grabs his two chopsticks so he can eats.

 

So far so good - However to complicate things the philosophers share their chopsticks.

Each philosopher's right chopstick is shared with his neighbor on the right and his left chopstick is shared with his neighbor on the left.

 

The problem

what happens if Plato would pick his right chopstick but when he tries to grab his left chopstick it is already taken by his colleague‏‏‏‏?

Obviously being Plato he is patient enough to wait till his fellow thinker finish his snack and put his chopsticks down. however to insure that he does get to eat in the near future Plato keeps the chopstick he managed to get till he can grab the other chopstick.

This behavior can cause a deadlock if each philosopher takes the chopstick to his right at the same time.

 

The program

As we can see from the story each philosopher does the following actions:

  1. Think for a while
  2. Take the chopstick to your right
  3. Take the chopstick to your left
  4. Eat
  5. Put down the chopstick in your left hand
  6. Put down the chopstick in your right hand

 

As you can already see we can implement this behavior using locks - each chopstick is an object that the philosopher tries to lock. 

My implementation uses three classes:

1. Philosopher - to contain the bulk of our problem logic

2. Chopstick - I could use simple object instead but I like to properly define my classes

3. Table - to contain the overall problem domain

 

Philosopher class has left and right chopsticks and two functions: Think and TryToEat.

As you can see from the code below TryToEat use lock to acquire the chopsticks and then eat and exit.

 

public class Philosopher
{
private ChopStick rightChopstick, leftChopstick;
private int timeToThink;
private string name;

public Philosopher(string name, ChopStick rightChopstick, ChopStick leftChopstick, int timeToThink)
{
this.name = name;
this.rightChopstick = rightChopstick;
this.leftChopstick = leftChopstick;
this.timeToThink = timeToThink;
IsAlive = true;
}

public string Name { get { return name; } }
public bool IsAlive { get; set; }

public void Run()
{
while (IsAlive)
{
Think();
TryToEat();
}
}

public void Think()
{
Console.WriteLine("{0} is thinking", name);
Thread.Sleep(timeToThink);
Console.WriteLine("{0} done thinking", name);
}

public void TryToEat()
{
lock (rightChopstick)
{
Console.WriteLine("{0} grabbed right Chopstick", name);
lock (leftChopstick)
{
Console.WriteLine("{0} grabbed Left chopstick", name);
Console.WriteLine("{0} is eating", name);
}
}

Console.WriteLine("{0} has finished eating", name);
}
}


Remark:



in the real program I would have used Thread.Sleep to simulate the time it takes the philosopher to eat but for the example purpose I can do without it.



 



Typemock Racer



As we can tell the deadlock would happen in TryToEat function and so we can write the following test to check it:



[TestFixture]
public class DiningPhiloRacer
{
[Test]
public void DiningPhilosefers_Run_FindDeadlock()
{
var c1 = new ChopStick();
var c2 = new ChopStick();
var c3 = new ChopStick();

ThreadTest
.AddThreadAction(() => new Philosopher("Plato", c1, c2, 0).TryToEat())
.AddThreadAction(() => new Philosopher("Konfucius", c2, c3, 0).TryToEat())
.AddThreadAction(() => new Philosopher("Socrates", c3, c1, 0).TryToEat())
.Start();
}
}


 



Running the test is as simple as clicking a mouse button - and presto deadlock found.



diningPhilosophersDeadlock



Under the deadlock message we can see the scenario that caused the deadlock and with stack trace (blue rectangle) and if that's not enough the user is given an attribute (yellow rectangle) he can use in his\her test to quickly reproduce the scenario that caused the deadlock.



 



That's it for now



 



Stay tuned for other uses and tips from the Racer team

Sunday, June 1, 2008

Unit testing and TDD Resources

We are in the process of creating a resources page on beginning Test Driven Development and Unit testing in general. I

f there are any resources (blogs, articles, books, videos - anything that could be of interest) you think are essential for people to know about, do leave a comment on this post or send an email to royo at Typemock.com. We'd love to know if there is anything we are missing and we'll happily add it.

64 bit vs. 32 bits

There is a very good .NET Rocks episode onthe 64 and 32 bit differences. Since we run into this troublesome land all the time with Typemock Isolator, and it's profiling engine, we've found it very helpful and interesting! Do listen if you get the chance.

Wednesday, March 26, 2008

Great introduction tutorial for Typemock Isolator

I just wanted to let you know that Stephen Walther wrote an excellent introduction tutorial for Typemock Isolator.
The tutorial has emphasis towards Data Base testing.
You can read it here.  

Sunday, March 9, 2008

Testing MVC Controllers in 3 lines of code with Typemock Isolator

Here's a much simpler version of how you'd test an ASP.NET MVC Controller using Typemock, without needing any helper class to do it:

[TestMethod,VerifyMocks]
  public void Hello_ShowsTheHelloView2()
  {
      Mock mock = MockManager.Mock<HomeController>();
      mock.ExpectCall("RenderView").Args("Index");


      HomeController controller = new HomeController();
      controller.Index();
  }

This is possible because we can mock out the protected (non virtual ) method "RenderView" on the Controller itself, which saves us the trouble of even touching anything underneath it.

With this, you don't need to have any of the helper code we wrote about here. If your controller uses the request context however, you may want to still mock that out using the previously mentioned links .

Saturday, March 8, 2008

Testing ASP.NET MVC using Typemock Isolator

Update: There is a much simpler version of these tests that does not even require any helper classes. You may want to look at that as well.

 

Scott Hanselman posted his notes and slides (and movies!) from his talk on the ASP.NET MVC framework, where he also mentioned and shows how he's write unit tests for the MVC framework in ASP.NET.

Scott has examples both in Moq and Rhino.Mocks on how to write these tests, so it should be no surprise we'd want to get into the game.

You can download a zip file that contains the Typemock version of the Mvc mock Helpers here. This version should work with the enterprise version of Typemock, but we'll make a community edition available soon.

Here is the full source code of the mocking helper class.

 

using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using TypeMock;

namespace Typemock.Mvc
{
static class MvcMockHelpers
{
public static void SetFakeContextOn(Controller controller)
{
HttpContextBase context = MvcMockHelpers.FakeHttpContext();
controller.ControllerContext = new ControllerContext(new RequestContext(context, new RouteData()), controller);
}

public static void SetHttpMethodResult(this HttpRequestBase request, string httpMethod)
{

using (var r = new RecordExpectations())
{
r.ExpectAndReturn(request.HttpMethod, httpMethod);
}
}

public static void SetupRequestUrl(this HttpRequestBase request, string url)
{
if (url == null)
throw new ArgumentNullException("url");

if (!url.StartsWith("~/"))
throw new ArgumentException("Sorry, we expect a virtual url starting with \"~/\".");
var parameters = GetQueryStringParameters(url);
var fileName = GetUrlFileName(url);
using (var r = new RecordExpectations())
{
r.ExpectAndReturn(request.QueryString, parameters);
r.ExpectAndReturn(request.AppRelativeCurrentExecutionFilePath, fileName);
r.ExpectAndReturn(request.PathInfo, string.Empty);
}
}

static string GetUrlFileName(string url)
{
if (url.Contains("?"))
return url.Substring(0, url.IndexOf("?"));
else
return url;
}
static NameValueCollection GetQueryStringParameters(string url)
{
if (url.Contains("?"))
{
NameValueCollection parameters = new NameValueCollection();

string[] parts = url.Split("?".ToCharArray());
string[] keys = parts[1].Split("&".ToCharArray());

foreach (string key in keys)
{
string[] part = key.Split("=".ToCharArray());
parameters.Add(part[0], part[1]);
}

return parameters;
}
else
{
return null;
}
}
public static HttpContextBase FakeHttpContext(string url)
{
HttpContextBase context = FakeHttpContext();
context.Request.SetupRequestUrl(url);
return context;
}
public static HttpContextBase FakeHttpContext()
{
HttpContextBase context = MockManager.MockObject<HttpContextBase>().Object;
HttpRequestBase request = MockManager.MockObject<HttpRequestBase>().Object;
HttpResponseBase response = MockManager.MockObject<HttpResponseBase>().Object;
HttpSessionStateBase sessionState = MockManager.MockObject<HttpSessionStateBase>().Object;
HttpServerUtilityBase serverUtility = MockManager.MockObject<HttpServerUtilityBase>().Object;
using (var r = new RecordExpectations())
{
r.DefaultBehavior.RepeatAlways();
r.ExpectAndReturn(context.Response, response);
r.ExpectAndReturn(context.Request, request);
r.ExpectAndReturn(context.Session, sessionState);
r.ExpectAndReturn(context.Server, serverUtility);
}
return context;
}

}
}



And here is an example of how you can write tests with it:




 



using System.Collections;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using MvcApplication1;
using MvcApplication1.Controllers;
using NUnit.Framework;
using Typemock.Mvc;

namespace MvcAppTests
{
[TestFixture]
public class HomeControllerTests
{
[Test]
public void Hello_ShowsTheHelloView()
{
FakeViewEngine engine = new FakeViewEngine();
HomeController controller = new HomeController();
controller.ViewEngine=engine;
MvcMockHelpers.SetFakeContextOn(controller);

controller.Hello();
Assert.AreEqual("Hello",engine.CurrentViewContext.ViewName);

}

[Test]
public void RouteDefaultsWork()
{
var app = new GlobalApplication();
RouteCollection routes = new RouteCollection();
GlobalApplication.RegisterRoutes(routes);
var context = MvcMockHelpers.FakeHttpContext();
context.Request.SetupRequestUrl("~/home");

var data = routes.GetRouteData(context);
Assert.AreEqual("home",data.Values["controller"]);
Assert.AreEqual("Index",data.Values["action"]);
}
}

internal class FakeViewEngine : IViewEngine
{
public ViewContext CurrentViewContext;
public void RenderView(ViewContext viewContext)
{
CurrentViewContext = viewContext;
}
}
}


Wednesday, February 20, 2008

Video: Typemock Basics 2: Decorators

I'm happy to share with you a new video of the Typemock Isolator Basics Series - this time it is about a feature called "Decorators" - which allows you to extend the current testing framework you work with with custom attributes, regardless if you are working with NUnit MbUnit or otherwise.
In the movie I show how to write a custom attribute for [Repeat(times])] on a test, to be repeated X amount of times by creating an attribute that inherits from Typemock.DecoratorAttribute.


video

You can download the full wmv from here, and it will be available along with our other Typemock videos on our Multimedia page next week