Category Archives: 3649

A TraceListener For Tests

In my code, I make extensive use of debug assertions (see System.Diagnostics.Debug.Assert). These assertions are very helpful while debugging because you don’t need to step into every line of code to see if all pre-conditions are met. As soon as a pre-condition fails, an assertion failed window will pop up and will allow us to either abort, ignore or go to the assertion instruction (retry).


Imagine you have this code:

private void IKnowForSureThatANullStringWillNeverBePassed(string text)
{
    System.Diagnostics.Debug.Assert(string != null, “text is null.”);

    // …
}

Because this method is private, I have full control of what is passed to the text parameter, therefore I’m asserting that it will never be null. Because it might not be obvious that text will never be null, the assertion also acts as documentation.


I usually run my unit tests and integration test on debug compilations and these assertions would be helpful by making the test fail on an assertion fail instead of running through the method and failing with an NullReferenceException. That’s why I (and more people out there) wrote this simple TraceListener:

public class TraceListener : global::System.Diagnostics.TraceListener
{
    public static readonly TraceListener Default = new TraceListener();

    protected TraceListener()
    {
        this.Name = “Testing Trace Listener”;    
    }

    protected TraceListener(string name)
        : base(name)
    {
    }

    public override void Write(string message)
    {
    }

    public override void WriteLine(string message)
    {
    }

    public override void Fail(string message, string detailMessage)
    {
        var builder = new global::System.Text.StringBuilder();

        builder.Append(message);

        if (detailMessage != null)
        {
            builder.Append(” “);
            builder.Append(detailMessage);
        }

        throw new global::Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException(builder.ToString());

    }
}

This trace listener won’t write anything to anywhere. It will just throw an AssertFailedException if the Fail method is called, which is what happens when an assertion fails.


Because an assertion window is not desired when running the tests (specially if they are automated tests ran as part of a build process) it’s better to disable the assert UI on the configuration file of the test project.

<?xml version=1.0encoding=utf-8?>
<configuration>
    <system.diagnostics>
        <assert assertuienabled=false/>
        <trace>
            <listeners>
                <add name=TestTraceListenertype=PauloMorgado.TestTools.VisualStudio.UnitTesting.Diagnostics.TraceListener, PauloMorgado.TestTools.VisualStudio/>
            </listeners>
        </trace>
    </system.diagnostics>
</configuration>
You can find this and other tools on the PauloMorgado.TestTools on CodePlex.

How To Set Elements Of An Array Of A Private Type Using Visual Studio Shadows

Visual Studio uses Publicize to create accessors public for private members and types of a type.


But when you try to set elements of a private array of elements of a private type, things get complicated.


Imagine this hypothetic class to test:

public static class MyClass
{
    private static readonly MyInnerClass[] myArray = new MyInnerClass[10];

    public static bool IsEmpty()
    {
        foreach (var item in myArray)
        {
            if ((item != null) && (!string.IsNullOrEmpty(item.Field)))
            {
                return false;
            }
        }

        return true;
    }

    private class MyInnerClass
    {
        public string Field;
    }
}

If I want to write a test for the case when the array has “non empty” entries, I need to setup the array first.


Using the accessors generated by Visual Studio, I would write something like this:

[TestClass()]
public class MyClassTest
{
    [TestMethod()]
    public void IsEmpty_NotEmpty_ReturnsFalse()
    {
        for (int i = 0; i < 10; i++)
        {
            MyClass_Accessor.myArray[i] = new MyClass_Accessor.MyInnerClass { Field = i.ToString() };
        }

        bool expected = false;
        bool actual;

        actual = MyClass.IsEmpty();

        Assert.AreEqual(expected, actual);
    }
}

But the test will fail because, although the elements of the private array myArray can be read as MyClass_Accessor.MyInnerClass instances, they can’t be written as such.


To do so, the test would have to be written like this:

[TestClass()]
public class MyClassTest
{
    [TestMethod()]
    public void IsEmpty_NotEmpty_ReturnsFalse()
    {
        for (int i = 0; i < 10; i++)
        {
            MyClass_Accessor.ShadowedType.SetStaticArrayElement(“myArray”, new MyClass_Accessor.MyInnerClass { Field = i.ToString() }.Target, i);
        }

        bool expected = false;
        bool actual;

        actual = MyClass.IsEmpty();

        Assert.AreEqual(expected, actual);
    }
}

But, this way, we loose all the strong typing of the accessors because we need to write the name of the array field.


Because the accessor for the field is a property, we could write a set of extension methods that take care of getting the field name for us. Something like this:

public static class PrivateypeExtensions
{
    public static void SetStaticArrayElement<T>(this PrivateType self, Expression<Func<T[]>> expression, T value, params int[] indices)
    {
        object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value;

        self.SetStaticArrayElement(
            ((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name,
            elementValue,
            indices);
    }

    public static void SetStaticArrayElement<T>(this PrivateType self, Expression<Func<T[]>> expression, BindingFlags invokeAttr, T value, params int[] indices)
    {
        object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value;

        self.SetStaticArrayElement(
            ((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name,
            invokeAttr,
            elementValue,
            indices);
    }
}

Now, we can write the test like this:

[TestClass()]
public class MyClassTest
{
    [TestMethod()]
    public void IsEmpty_NotEmpty_ReturnsFalse()
    {
        for (int i = 0; i < 10; i++)
        {
            MyClass_Accessor.ShadowedType.SetStaticArrayElement(() => MyClass_Accessor.myArray, new MyClass_Accessor.MyInnerClass { Field = i.ToString() }, i);
        }

        bool expected = false;
        bool actual;

        actual = MyClass.IsEmpty();

        Assert.AreEqual(expected, actual);
    }
}

It’s not the same as the first form, but it’s strongly typed and we’ll get a compiler error instead of a test run error if we change the name of the myArray field.


You can find this and other tools on the PauloMorgado.TestTools on CodePlex.

Typemock Is Launching The ASP.NET Bundle – Get Free Licenses


Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle – and for the launch they are giving out FREE licenses to bloggers and their readers.


The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator and Ivonna, the ASP.NET Isolator add-on, for a discounted price.


ASP.NET Bundle launch giveaway:
For the ASP.NET Bundle launch Typemock are giving away free licenses to bloggers and their readers.


How do I get the free license?


Are you a blogger, webmaster, or internet columnist? Get your free license by helping Typemock launch their new ASP.NET Bundle, the ultimate ASP.NET unit testing solution.


Post the text below on your blog (as is, with links) and tell them about it . If you are in the first 60 to mail us after posting, your license will be on its way!


If you have an ASP.NET dedicated blog, you’ll get a license automatically (even if more than 60 submit) during the first week of this announcement.


8 bloggers will also get an additional 2 licenses (each) to give away / raffle to their readers or friends.


A few simple requirements:


  1. You must own a website, blog space or internet column, older than 2 months, or get permission from the owner of such a site.
  2. Your post must include the text below (including the links) between *Begin* and *End*.

*Begin*


Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.


Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle – and for the launch will be giving out FREE licenses to bloggers and their readers.


The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.


Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.


The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you’ll get a license automatically (even if more than 60 submit) during the first week of this announcement.


Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.


Go ahead, click the following link for more information on how to get your free license.


*End*


Once you post this in your site, just drop them a line at asp@typemock.com with your name and the post URL to get your free license.


Hurry up – this offer is limited to the first 60 bloggers, or to ASP.NET dedicated bloggers who will post this in the first week.


Make sure to follow their Blog, Site or Twitter for updates on this event.


Unit Test Today! Get Typemock Isolator!

Help Typemock Launch Its New Visual Basic .NET Friendly API And You Might Get A Free License


Typemock is announcing today a new version of Typemock Isolator (5.2).


One of the coolest features in the new version is the inclusion of a new VB .NET unit testing API. This ‘VB friendly’ API was designed and written in VB.NET, for VB.NET developers. It uses the strengths of the VB.NET language to allow easy and intuitive use of the isolation API, for easier unit tests on any piece of .NET code.


If you are you a blogger, webmaster, or internet columnist, you can get your free personal license by helping Typemock launch their new 5.2 version for Isolator – the best tool to unit test VB.NET applications.


Although this version is targeted to unit test VB.NET applications, C# applications with unit tests built using Visual Studio 2005 can also benefit from this API.


How can you get the free license?


Post the text below on your blog (as is, with links) and tell them about it . If you are in the first 25 to mail them after posting, your license will be on its way!


If you have a VB.NET dedicated blog, you’ll get a license automatically (even if more than 25 submit) during the first week of this announcement.


A few simple requirements:


  1. You must own a website, blog space or internet column, older than 2 months, or get permission from the owner of such a site.
  2. Your post must include the text below (including the links) between *Begin* and *End*.

_


*Begin*


Programming Visual Basic applications?


Typemock have released a new version of their unit testing tool, Typemock Isolator 5.2.
This version includes a new friendly VB.NET API which makes Isolator the best Isolation tool for unit testing A Visual Basic (VB) .NET application.


Isolator now allows unit testing in VB or C# for many ‘hard to test’ technologies such as SharePoint, ASP.NET MVC, partial support for Silverlight, WPF, LINQ, WF, Entity Framework, WCF unit testing and more.


Note that the first 25 bloggers who blog this text in their blog and tell us about it, will get a Free Full Isolator license (worth $139). If you post this in a VB.NET dedicated blog, you’ll get a license automatically (even if more than 25 submit) during the first week of this announcement.


Go ahead, click the following link for more information on how to get your free license.


_


*End*


Once you post this in your site, just drop them a line at vb@typemock.com with your name and the post URL to get your free license.


Hurry up – this offer is limited to the first 25 general bloggers, or to VB.NET dedicated bloggers who will post this in the first week.



Disclaimer: This is an offer from Typemock as announced at http://blog.typemock.com/2009/01/get-free-isolator-licnese-for-helping.html. I’m just a fan.

Improving Debugging And Testing Through Assertions

Reading through the The Typemock Insider blog, I came across this post from Gil Zilberfeld.

I myself tend to fall in Gil’s practice ("binary search" debugging), but I don’t think Kent Beck has the right solution.

Gil’s suggestion of using Isolator is tempting (I don’t miss an opportunity to use it), but still not my favorite one.

I prefer to use debug assertions. Debug assertions can be used when running a debug version of the application to pop-up assertion messages and when running unit tests to fail tests.

In order to use debug assertions in unit tests a “special” trace listener is needed to make the test fail when its Fail method is called.

public class UnitTestTraceListener : global::System.Diagnostics.DefaultTraceListener
{
     public UnitTestTraceListener() : base()
    {
        this.Name = "UnitTest";
        this.AssertUiEnabled = false;
    }

    public override void Fail(string message, string detailMessage)
    {
        Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail("Debug.Assert Failed: " + message + " " + detailMessage);
    }
}



Now, all you need to do is register it.




Registering the trace listener can either be done in code:




System.Diagnostics.Trace.Listeners.Remove("Default");
System.Diagnostics.Trace.Listeners.Add(new UnitTestTraceListener());



or configuration:




<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <assert assertuienabled="false"/>
    <trace>
      <listeners>
        <clear/>
        <add name="UnitTest" type="UnitTestTraceListener"/>
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>



And if I’m using Isolator I have the take in account the accesses made in the call to the Assert method. More fun to me.


Typemock Isolator 5.1 Released

This major version adds static method support and non-public method faking to the AAA API. Check out the release notes.

I don’t like the reflective approach to testing private methods.

With the new additions to the AAA API, testing this class:

public class MyClass
{
    public string Public()
    {
        return this.Private();
    }

    private string Private()
    {
        throw new NotImplementedException();
    }
}



can be done like this:




[TestMethod]
[Isolated]
public void PrivateTest()
{
    MyClass fake = Isolate.Fake.Instance<MyClass>();

    Isolate.WhenCalled(() => fake.Public()).CallOriginal();

    Isolate.NonPublic.WhenCalled(fake, "Private").WillReturn("FAKE");

    string fakePublic = fake.Public();

    Assert.AreEqual("FAKE", fakePublic);

    Isolate.Verify.WasCalledWithExactArguments(() => fake.Public());

    Isolate.Verify.NonPublic.WasCalled(fake, "Private");
}



I would like it better if it was like this:




[TestMethod]
[Isolated]
public void PrivateTest()
{
    MyClass fake = Isolate.Fake.Instance<MyClass>();

    MyClass_Accessor fakeAccessor = MyClass_Accessor.AttachShadow(fake);

    Isolate.WhenCalled(() => fakeAccessor.Private()).WillReturn("FAKE");

    Isolate.WhenCalled(() => fake.Public()).CallOriginal();

    string fakePublic = fake.Public();

    Assert.AreEqual("FAKE", fakePublic);

    Isolate.Verify.WasCalledWithExactArguments(() => fake.Public());

    Isolate.Verify.WasCalledWithExactArguments(() => fakeAccessor.Private());
}



Looks almost the same but there aren’t any method names in the test code.




They were able to do it for Natural Mocks. I’m sure they will eventually do it for AAA.

Faking Output Parameters With Typemock Isolator

Some time ago I was asked if it was possible to fake output parameters with Typemock Isolator.

It’s actually very easy using any of the APIs.

Given this class:

public class MyClass
{
    public bool MyMethod(string input, out int output1, out double output2)
    {
        throw new NotImplementedException();
    }
}




Using the new AAA API, it’s as clean as:



[TestMethod]
[Isolated]
public void TestMethodIsolated()
{
    MyClass target = Isolate.Fake.Instance<MyClass>();

    string input = "test value";
    int expectedOutput1 = 1;
    double expectedOutput2 = 2;

    Isolate.WhenCalled(() => target.MyMethod(input, out expectedOutput1, out expectedOutput2)).WillReturn(true);

    int output1;
    double output2;
    bool result = target.MyMethod(input, out output1, out output2);

    Assert.IsTrue(result);
    Assert.AreEqual<int>(expectedOutput1, output1);
    Assert.AreEqual<double>(expectedOutput2, output2);
}



Using Natural Mocks, it’s as easy as:




[TestMethod]
[VerifyMocks]
public void TestMethodNatural()
{
    MyClass target = RecorderManager.CreateMockedObject<MyClass>();

    string input = "test value";
    int expectedOutput1 = 1;
    double expectedOutput2 = 2;

    using (RecordExpectations recorder = RecorderManager.StartRecording())
    {
        recorder.ExpectAndReturn(target.MyMethod(input, out expectedOutput1, out expectedOutput2), true);
    }

    int output1;
    double output2;
    bool result = target.MyMethod(input, out output1, out output2);

    Assert.IsTrue(result);
    Assert.AreEqual<int>(expectedOutput1, output1);
    Assert.AreEqual<double>(expectedOutput2, output2);
}



It’s also possible using Reflective Mocks:




[TestMethod]
[VerifyMocks]
public void TestMethodReflective()
{
    MockObject<MyClass> targetMock = MockManager.MockObject<MyClass>();

    string input = "test value";
    int expectedOutput1 = 1;
    double expectedOutput2 = 2;

    targetMock.ExpectAndReturn(
        "MyMethod",
        new DynamicReturnValue(delegate(object[] parameters, object context)
            {
                parameters[1] = expectedOutput1;
                parameters[2] = expectedOutput2;
                return true;
            }));

    int output1;
    double output2;
    bool result = targetMock.Object.MyMethod(input, out output1, out output2);

    Assert.IsTrue(result);
    Assert.AreEqual<int>(expectedOutput1, output1);
    Assert.AreEqual<double>(expectedOutput2, output2);
}



All you have to do is choose which one you like most.


Isolator 4.3 Released!

Today Typemock released version 4.3 of Typemock Isolator. Download it from here.

What’s new?

  • Support for Ivonna. For those of you who develop ASP.Net applications, Ivonna is a great tool, built on top of Isolator’s platform, to simplify writing tests for ASP.NET.
  • Typemock.Integration.Packs namespace APIs added to support license management through Isolator, the way Ivonna does.
  • As announced when it was released, version 4.2 was the last version of Isolator to support .NET 1.1. Version 4.3 only supports the 2.0 runtime and its Visual Studio counterparts: VS2005 and VS2008.
  • For 64 bit machines, now there’s a single installer. (don’t forget to uninstall both previous 32 and 64 installers prior to installing 4.3.)
  • RecorderManager.GetMockOf(instanceRef) and MockManager.GetMockOf(instanceRef). To retrieve the mock controller object based on a reference to the instance. (more…).

Bug fixes:

  • Fixes to DLINQ support. LINQ Queries with data tables now work better, for example with GroupBy.
  • Static constructors in Natural Mocks are now invoked correctly.
  • A bug that caused an exception to be thrown when mocking interfaces ("Method XX in type IMyInterface has no matching overload that returns TypeMock.Mock+a) was fixed.
  • A bug that caused an exception to be thrown when the mocked object was overriding Equals was fixed.
  • A bug that caused failure in mocking explicit interface with the same name was fixed.
  • A bug occurring im multithreading scenarios in VerifyWithWait was fixed.
  • A bug that causes NullReferenceException to be thrown when using Auto Deploy was fixed.

See also: