Archive for the ‘.NET’ Category

Post

Raising events in NMock

In .NET on March 4, 2009 by Sid

It is actually pretty easy to raise events using the latest release of NMock. You can basically use Expect.Once.On(bla).EventAdd(“SomeEvent”, Is.Anything) to specify that you expect an event handler to be added for “SomeEvent” event on bla object and fire that event using Fire.Event(“SomeEvent”).

Here’s an example, minus any domain noise, that demonstrates the whole thing.

Read More »

Post

Interfaces and partial classes

In .NET on February 13, 2009 by Sid

What will happen when the following piece of code is compiled?

class Program
{
static void Main(string[] args)
{
ICanMove monkey = new Monkey();
monkey.Move();
}
}

public interface ICanMove
{
void Move();
}

public partial class Monkey : ICanMove
{
}

public partial class Monkey
{
public void Move()
{
Console.WriteLine(“Moved”);
}
}

Options:

  1. Compiler error.
  2. “Moved” will be printed.

Read More »

Post

Preventing tracing of sensitive information in logs generated using .NET trace classes

In .NET on December 17, 2008 by Sid Tagged: ,

If you have an application that deals with payment processing, social-security numbers, etc., there’s a possibility that such sensitive information can be written to log by a component in the application. While you need to take appropriate measures to ensure that the log files are sufficiently protected, you may also want to prevent such information from being logged altogether. And if that’s the case, here’s something that can help.

TraceCheckingListener is a custom TraceListener which checks each incoming trace message for the presence of credit-card numbers and causes the trace to fail by throwing an exception if one is found.

public class TraceCheckingListener : TraceListener
{
private const string CreditCardRegEx = @”(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})”;
private Regex regex;

public TraceCheckingListener()
{
this.regex = new Regex(CreditCardRegEx, RegexOptions.Compiled);
}

private bool ContainsCreditCardNumber(string text)
{
return (!String.IsNullOrEmpty(text)) && this.regex.IsMatch(text);
}

public override void Write(string message)
{
if (this.ContainsCreditCardNumber(message))
throw new InvalidOperationException(“Sensitive credit-card information cannot be logged.”);
}

public override void WriteLine(string message)
{
if (this.ContainsCreditCardNumber(message))
throw new InvalidOperationException(“Sensitive credit-card information cannot be logged.”);
}
}

It currently checks for Visa, MasterCard, American Express, Discover, Diners Club and JCB credit-cards.

TraceChecker is a small utility class which can be instantiated in a C# using block to install the TraceCheckingListener while the using block executes and remove it when it’s done.

public class TraceChecker : IDisposable
{
private TraceCheckingListener traceCheckingListener;

public TraceChecker()
{
this.traceCheckingListener = new TraceCheckingListener();
Trace.Listeners.Insert(0, this.traceCheckingListener);
}

#region IDisposable Members

public void Dispose()
{
if (this.traceCheckingListener != null)
{
Trace.Listeners.Remove(this.traceCheckingListener);
this.traceCheckingListener = null;
}
}

#endregion
}

One way to make use of these classes is to introduce the following class in your unit-test suite assembly.

[TestClass]
public class TraceCheckerInstaller
{
private static TraceChecker traceChecker;

[AssemblyInitialize]
public static void InstallTraceChecker(TestContext context)
{
traceChecker = new TraceChecker();
}

[AssemblyCleanup]
public static void UninstallTraceChecker()
{
if (traceChecker != null)
{
traceChecker.Dispose();
traceChecker = null;
}
}
}

InstallTraceChecker will be called only once when the assembly containing the unit-tests is loaded so we use the opportunity to install the custom trace-listener. UninstallTraceChecker will be called once when the assembly is being unloaded which we use to remove the custom trace-listener.

Alternately, you may also utilize the following approach in individual unit-tests.

[TestMethod]
public void MyTestMethod()
{
using (new TraceChecker())
{
// Write code to test whatever you want to test here.
// This test will fail if any method called from here
// attemps to trace sensitive information to the log.
}
}

Post

Mocking functions taking variable number of args using C# params keyword

In .NET on December 16, 2008 by Sid Tagged:

Consider the following interface that takes a variable number of arguments in its Add method.

public interface IAdder
{
string Add(params string[] items);
}

And consider that we have to test the following function which invokes Add with two arguments.

public string AddStrings(string one, string two, IAdder adder)
{
return adder.Add(one, two);
}

The expectation created below is incorrect:

string[] args = new string[] { “FOO”, “BAR” };
IAdder adder = mocks.NewMock();
string expected = “FOOBAR”;

Expect.Once.On(adder).Method(“Add”).With(args).Will(Return.Value(expected));

string actual;
actual = target.AddStrings(args[0], args[1], adder);
Assert.AreEqual(expected, actual);

It will cause NMock to generate the following exception because NMock is expecting two distinct arguments to Add with values “FOO” and “BAR” instead of an array of strings containing “FOO” and “BAR”.

NMock2.Internal.ExpectationException occurred
Message=”unexpected invocation of adder.Add()\r\nExpected:\r\n 1 time: adder.Add(equal to \”FOO\”, equal to \”BAR\”), will return \”FOOBAR\” [called 0 times]\r\n”

You need to change the expectation so that NMock compares the string-array.

Expect.Once.On(adder).Method(“Add”).With(Is.EqualTo(args)).Will(Return.Value(expected));

That’ll do the trick.

Post

Fluently mocking fluent APIs

In .NET on December 15, 2008 by Sid Tagged: ,

The best thing about fluent-style APIs is that they are readable and flow easily. Consider the following for example:

customer.NewOrder
.With(1, “ONE”)
.With(2, “TWO”)
.With(3, “THREE”)
.PriorityRush();

The API used above is clearly more readable than:

Order o1 = new Order();
customer.AddOrder(o1);
OrderItem item1 = new OrderItem(1, “ONE”);
o1.Add(item1);
OrderItem item2 = new OrderItem(2, “TWO”);
o1.Add(item2);
OrderItem item3 = new OrderItem(3, “THREE”);
o1.Add(item3);
o1.SetRush();

Another reason I like them is that fluent style APIs are easier to pick up. You can rely on intellisense to guide you more as you have to worry about lesser number of class and method names.

So they’re nice, but I hate to see code like the following that has to do a lot of setting up before you can actually make a call to the function you wish to test from your unit-test:

[TestMethod()]
public void PlacePriorityOrderTest()
{
using (Mockery mocks = new Mockery())
{
int itemID = 42;
string itemDescription = “SOMETHING”;

Program target = new Program();

// Start setting up NMock expectations…
ICustomer customer = mocks.NewMock();
IOrderActions mockOrderActions = mocks.NewMock();
Expect.Once.On(customer).GetProperty(“NewOrder”).Will(Return.Value(mockOrderActions));
IOrderActions mockOrderItemActions = mocks.NewMock
();
Expect.Once.On(mockOrderActions).Method(“With”).With(itemID, itemDescription).Will(Return.Value(mockOrderItemActions));
Expect.Once.On(mockOrderItemActions).Method(“PriorityRush”);
// End setting up NMock expectations…

// Call the function we wish to test
target.PlacePriorityOrder(customer, itemID, itemDescription);
}
}

Here is the function that the test above is exercising:

public void PlacePriorityOrder(ICustomer customer, int itemID, string itemDescription)
{
customer.NewOrder.With(itemID, itemDescription).PriorityRush();
}

The test is just making sure that the item-id and item-description passed to PlacePriorityOrder are used to create a new order with priority-rush. There’re probably going to be many tests that exercise the same fluent-API and they’d all be doing similar setting up of mock objects.

It would be better if the expectation was specified in a fluent manner as well.

[TestMethod()]
public void PlacePriorityOrderTest2()
{
using (Mockery mocks = new Mockery())
{
int itemID = 42;
string itemDescription = “SOMETHING”;

Program target = new Program();

MockCustomer mockCustomer = MockCustomer.Record(mocks);
mockCustomer.NewOrder.With(itemID, itemDescription).PriorityRush();

target.PlacePriorityOrder(mockCustomer.Start(), itemID, itemDescription);
}
}

Notice the call to MockCustomer.Record to return a mock ICustomer instance that can be used to record calls to various methods that the test expects to be made. Also note that mockCustomer.Start is used to retrieve the mock ICustomer instance that’s actually used by the function under test.

The zip archive here contains code demonstrating how this can be done.

Post

Testing methods that depend upon a singleton class

In .NET on December 11, 2008 by Sid Tagged: , , ,

Singleton is probably one of the most (mis-)used design patterns. In this article I intend to lay out a scenario and then demonstrate how we can go about testing methods that depend upon a singleton class. Finally I’ll recap the whole approach in a bulleted list for easy reference.

Let’s restrict our problem to involve just 2 classes for the purpose of this article. Assume there’s already a class named Transaction and we’re interested in testing its CompleteTransaction method.

public class Transaction
{
public void CompleteTransaction()
{
DeviceManager.Instance.OpenCashDrawer();
}
}

In our test we plan to ensure that CompleteTransaction calls the OpenCashDrawer method of DeviceManager.

public sealed class DeviceManager
{
private static readonly DeviceManager instance = new DeviceManager();

private DeviceManager()
{
}

public static DeviceManager Instance
{
get
{
return instance;
}
}

public void OpenCashDrawer()
{
// Code for opening cash-drawer will go here.
Console.WriteLine(“CashDrawer opened…”);
}

}

DeviceManager is a singleton and there lies our problem. If there was an interface that DeviceManager implemented and CompleteTransaction took an object implementing that interface as argument we could have used NMock to mock that interface and created expectations in our test to expect a call to its OpenCashDrawer method when CompleteTransaction is called. We want to reduce the code churn so another alternative is needed. Changing the singleton semantics of DeviceManager or changing the CompleteTransaction method’s signature – are alternatives which will potentially require modification of a lot of code and testing it.

But having an interface in the picture will make our job easier so here’s what we can do.

  1. Extract interface: We can extract an interface containing all the methods contained in DeviceManager class. Let’s say, we’re going to call it IDeviceManager.
  2. Change types: We can then modify the type of static instance field and static Instance property to be IDeviceManager instead of DeviceManager.
  3. Plant mock: In our test for CompleteTransaction method if we could somehow plant a mock object implementing IDeviceManager in the DeviceManager.instance field, we can then create an expectation in our test saying that expect a call to OpenCashDrawer method.

Extract interface

This is easy to do in our example. In the real world, especially for a class that has been around for years, there could potentially be hundreds of methods. If that’s the case you have, take a look at the DevExpress Refactor add-in for Visual Studio which just requires you to right-click on a class and select “Extract interface”.

In our example, here’s what we end up with:

public sealed class DeviceManager : IDeviceManager
{
private static readonly DeviceManager instance = new DeviceManager();

private DeviceManager()
{
}

public static DeviceManager Instance
{
get
{
return instance;
}
}

public void OpenCashDrawer()
{
// Code for opening cash-drawer will go here.
Console.WriteLine(“CashDrawer opened…”);
}

}

public interface IDeviceManager
{
void OpenCashDrawer();
}

At this point all of your code should compile just fine.

Change types

We simply change the type of instance field and Instance property to be IDeviceManager.

public sealed class DeviceManager : IDeviceManager
{
private static IDeviceManager instance = new DeviceManager();

private DeviceManager()
{
}

public static IDeviceManager Instance
{
get
{
return instance;
}
}

public void OpenCashDrawer()
{
// Code for opening cash-drawer will go here.
Console.WriteLine(“CashDrawer opened…”);
}

}

public interface IDeviceManager
{
void OpenCashDrawer();
}

Again at this point the code should compile just fine. If it doesn’t, as would be the case where you have code that saves an instance of DeviceManager in a local variable before doing stuff with it, you’ll have to refactor that code to get rid of all compilation errors.

Plant mock

How do we plant a mock-object in the private static field DeviceManager.instance?

  1. We start by making use of the private-accessors feature of Visual Studio 2008. Right-click on DeviceManager class and select “Create Private Accessors”. You can read more about private accessors here. The basic idea is that a DeviceManager_Accessor class will be created mirroring the public methods of DeviceManager but additionally also exposing its private and protected fields. Internally a DeviceManager_Accessor object manages a DeviceManager object and forwards all method calls and field accesses to it. You can also create private-accessors from the Visual Studio command-prompt using “publicize ”.
  2. We write our test to create a mock-object implementing IDeviceManager and plant it in the DeviceManager’s static instance field using DeviceManager_Accessor.

    IDeviceManager mockDeviceManager = mocks.NewMock< IDeviceManager>();
    DeviceManager_Accessor.instance = mockDeviceManager;

  3. But there’s something to watch out for. It is possible that this test runs as part of a suite of tests so you want to ensure that DeviceManager.Instance returns a normal DeviceManager object after your test has finished executing. It is not sufficient to set DeviceManager_Accessor to null – you must restore the DeviceManager_Accessor.instance field to whatever its value was before you set it to a mock object. Since we want to ensure that the instance static field gets reset even if our test code throws an exception, we do the resetting in a finally block. Here’s what the test-method’s body would look like.

    using (Mockery mocks = new Mockery())
    {
    // save
    IDeviceManager prevDeviceManager = DeviceManager_Accessor.instance;

    try
    {
    // plant
    IDeviceManager mockDeviceManager = mocks.NewMock();
    DeviceManager_Accessor.instance = mockDeviceManager;

    // TODO: write test code here.
    }
    finally
    {
    // restore
    DeviceManager_Accessor.instance = prevDeviceManager;
    }
    }

The test

Now that we have everything in place, let’s write the actual test code. Before calling CompleteTransaction, we create an NMock expectation to ensure that OpenCashDrawer is called on the mock IDeviceManager object.

[TestMethod()]
public void CompleteTransactionTest()
{
using (Mockery mocks = new Mockery())
{
// save
IDeviceManager prevDeviceManager = DeviceManager_Accessor.instance;

try
{
// plant
IDeviceManager mockDeviceManager = mocks.NewMock();
DeviceManager_Accessor.instance = mockDeviceManager;

// we expect OpenCashDrawer to be called
Expect.Once.On(mockDeviceManager).Method(“OpenCashDrawer”);

// the actual
Transaction target = new Transaction();
target.CompleteTransaction();
}
finally
{
// restore
DeviceManager_Accessor.instance = prevDeviceManager;
}
}

}

Run the test and it should pass. Change the body of CompleteTransaction method to not make a call to OpenCashDrawer and the test should fail.

Recap of the approach

  1. Extract an interface from the singleton class.
  2. Modify the singleton class to implement the newly created interface.
  3. Modify the type of the static field (= VB.NET shared) holding a reference of the singleton class, and the return-type of the method/property returning the singleton to be same as the newly created interface.
  4. Generate an accessor assembly for the assembly containing the singleton class for use in your unit-tests.
  5. Write your unit-test to create a mock object implementing the newly introduced interface and plant it in the static field of the singleton class.
  6. Create necessary expectations on various methods on the newly introduced interface which you expect to be called by the function under test.
  7. Once your test is finished, ENSURE that the previous singleton is restored (using finally block).

If, however, you’re in the process of writing a new singleton class in your project, consider introducing an interface and create a façade which everyone would use to obtain an instance of your class implementing that interface. This will probably save you from having to revisit this article in the future :)

Click here to download a zip archive containing the code shown in this article.

Post

Using Pex to test VB.NET code

In .NET,Tech/Hacks on December 2, 2008 by Sid Tagged: , , ,

In an ideal world one would write unit-tests before writing any new code following the tenants of TDD. In reality it is quite common to have to rely on a legacy library to do some heavy lifting. Pex is a great new tool available from Microsoft Research that can be used to generate unit-tests automatically. It is smart in that it runs the function you wish to test trying to exercise all possible code paths and ultimately generates unit-tests that can be used to test that function.

Using Pex is as easy as right-clicking on a function in Visual Studio and selecting “Run Pex Explorations”. Pex takes a little while running your function and then displays a table with various values that can be used to test your function.

However if your legacy code happens to be in VB.NET, you cannot just right-click on a function to have Pex generate all unit-tests for you. So that’s where I hope this article will help you.

First, let’s define a scenario. Imagine there’s a class called Transaction and a class called PaymentMethod. A transaction contains various payment-methods. A PaymentMethod indicates whether it requires the cash-drawer to be opened or not (e.g. it doesn’t make sense to pop cash-drawer for a credit-card while it does for cash and debit-card). There’s a read-only property PopCashDrawer on Transaction which returns true if any of the payment-methods requires the cash-drawer to be opened.

Public Class PaymentMethod

Private mPopCashDrawer As Boolean

Public Property PopCashDrawer() As Boolean
Get
Return Me.mPopCashDrawer
End Get
Set(ByVal value As Boolean)
Me.mPopCashDrawer = value
End Set
End Property

End Class

Public Class Transaction

Private mPaymentMethods() As PaymentMethod

Public Property PaymentMethods() As PaymentMethod()
Get
Return Me.mPaymentMethods
End Get
Set(ByVal value As PaymentMethod())
Me.mPaymentMethods = value
End Set
End Property

Public ReadOnly Property PopCashDrawer() As Boolean
Get
Dim pop = False
For Each pm As PaymentMethod In Me.PaymentMethods
pop = pop OrElse pm.PopCashDrawer
Next
Return pop
End Get
End Property

End Class

To have Pex generate unit-tests for you, here’s what you need to do:

  • First to get started writing unit-tests, just right-click on Transaction in Visual Studio and select “Create Unit Tests”. Make sure you select “Create a new Visual C# project” for Output Project in the dialog that pops up.
  • Next, in the generated class TransactionTest add the following parameterized unit-test (PUT). This guides Pex to come up with different values of arguments to this method which will exercise all code-paths in PopCashDrawer property. Transaction.PopCashDrawer depends upon the PaymentMethods so we take the array of PaymentMethods as argument to our PUT and set it on the transaction before calling PopCashDrawer. The PexAssume.IsNotNull line further guides Pex to say that we don’t really care about the case when transaction is null because we’re really interested in testing PopCashDrawer method.

    [PexMethod]
    public bool PopCashDrawerPUT(Transaction transaction, PaymentMethod[] paymentMethods)
    {
    PexAssume.IsNotNull(transaction);
    transaction.PaymentMethods = paymentMethods;
    return transaction.PopCashDrawer;
    }

  • Next, just right-click on PopCashDrawerPUT and select “Run Pex Explorations”. Pex will then display a table with various values of arguments and the results it got in each case.
  • However since the VB assembly is separate from the C# test-project, Pex will display an icon indicating that it didn’t explore some methods because they were uninstrumented.
  • Make sure you include all methods displayed as uninstrumented and run Pex explorations again.
  • This time around Pex would show 7 different test-cases that it identified.
  • A file named TransactionTest.PopCashDrawerPUT.g.cs would be generated containing unit-tests for those 7 cases. Take a look at that class to see how much work it saved you.
  • You can run the generated unit-tests by going to Test->Run->All Tests in Solution from the main-menu in Visual Studio.
  • Pex would discover inputs which cause PopCashDrawer to throw a NullReferenceException. Determining fixes for those cases is left as an exercise to the reader :)

Download and try out Pex, if you haven’t already!

Post

Mocking indexers with NMock

In .NET,Tech/Hacks on November 25, 2008 by Sid Tagged: ,

Indexers allow objects to behave like arrays. Dictionary class in .NET, for example, provides an indexer that allows the retrieval of the item from the dictionary that corresponds to a particular key.

There are two ways you can go about mocking indexers defined on interfaces when using NMock.

  1. You can use the Get property to describe what should be returned when a particular parameter is passed. The following expectations for example, cause “xxx” to be returned when foo[“aaa”] or foo[“bbb”] is called.

    Expect.Once.On(foo).Get["aaa"].Will(Return.Value(“xxx”));
    Expect.Once.On(foo).Get["bbb"].Will(Return.Value(“xxx”));

    This approach works fine in most circumstances. However you are required to provide all the values with which the indexer can be invoked. This presents a problem in the scenario where you need to return a particular value irrespective of the value of the input parameter.

  2. Indexers are implemented under the hood as methods so NMock’s support for mocking methods can be used to mock indexers. An indexer definition is munged by the compiler to a pair of get_Item and set_Item methods. When you call foo[“aaa”], it is munged by the compiler to a call to the get_Item method on foo with “aaa” as the argument.

    So here’s what you can do to make sure that “xxx” is returned irrespective of the value of the parameter passed to the indexer.

    Stub.On(foo).Method(“get_Item”).Will(Return.Value(“xxx”));

    Now any call of the form foo[<BLAH>] will return “xxx”.

Post

Automating windows forms UI testing

In .NET,General,Tech/Hacks on November 6, 2008 by Sid Tagged: , ,

If you have been blessed with a windows-forms application that has business-logic invading the user-interface, I have something that’ll help you. The most practical approach in this situation is to rearchitect the business layer and switch the UI over in a piecemeal fashion. While you’re doing this, automated testing of the user-interface will make your job a lot faster compared to manual testing.

For the purpose of this article let us consider a simple Windows Forms application (download link below). The application allows the user to provide two inputs and then either add them or subtract them. Simple, right?

The application
screenshot

Here’s the code for the event-handlers of interest to us:

private void MainForm_Load(object sender, EventArgs e)
{
this.lblAnswer.Text = “0″;
}

private void btnAdd_Click(object sender, EventArgs e)
{
this.lblAnswer.Text = Convert.ToString(this.numericUpDown1.Value + this.numericUpDown2.Value);
}

private void btnSubtract_Click(object sender, EventArgs e)
{
this.lblAnswer.Text = Convert.ToString(this.numericUpDown1.Value – this.numericUpDown2.Value);
}

The handler for the load event of the form just sets the answer label to display “0”. The handler for the click event of each of the buttons retrieves the selected values from the numeric drop-downs, applies the appropriate operation, and writes the result into the label.

The tests

In order to write tests for this application, you can start by right-clicking on the class of the form (in this case MainForm), and selecting “Create Unit Tests…”. Hit “OK” on the dialog that pops up to create unit-tests in a separate project. Another dialog will pop up asking for the name of the test project. Just hit “Create”.

This will cause Visual Studio to do some heavy lifting for us and generate accessors to allow us to call methods and properties defined on MainForm, from our tests. We don’t have to write code for accessors using the Reflection API ourselves – so this is extremely cool. Doing it on our own is quite painful (proof).

Delete all the tests marked with the TestMethod attribute in the generated class because we’re going to write our own.

The first one is pretty simple. We expect the answer label to display a “0” when the form is initially loaded – so let’s test that.

///

///A test for MainForm_Load
///

[TestMethod()]
[DeploymentItem("AppUnderTest1.exe")]
public void MainForm_LoadTest()
{
MainForm_Accessor target = new MainForm_Accessor();
target.MainForm_Load(null, null);
Assert.AreEqual(“0″, target.lblAnswer.Text, “Initial answer is zero”);
}

Notice that we can call MainForm_Load directly (no ConstructorInfo, MethodInfo – reflection stuff required).

Once that’s done we can just check the text displayed in the answer label and make sure it is “0”.

We can take the same approach to call the click event handlers of the buttons and check the results for addition/subtraction.

Since there are various cases to test, I have a separate function GetTestTable that returns a two dimensional array where each row contains the two test-inputs, result of subtraction, and result of addition – in that order.

public int[,] GetTestTable()
{
// Format of each row:
// A, B, (A-B), (A+B)
int[,] table =
{
{0, 0, 0, 0},
{10, 0, 10, 10},
{0, 10, -10, 10},
{-10, 0, -10, -10},
{0, -10, +10, -10},
{10, 10, 0, 20},
{-10, -10, 0, -20},
{-10, 10, -20, 0},
{10, -10, 20, 0}
};
return table;
}

Following is the function that actually does the testing. We basically process each row returned by GetTestTable one by one. First we set the two inputs on the numeric drop-downs. Next we call the click event-handlers of both buttons verifying what is in the answer label against what we expect. Again notice that we can directly invoke the event handlers and even access properties of the answer label (lblAnswer).

///

///A test for btnSubtract_Click
///

[TestMethod()]
[DeploymentItem("AppUnderTest1.exe")]
public void AddSubtractTest()
{
MainForm_Accessor target = new MainForm_Accessor();

int[,] table = this.GetTestTable();

for (int i = 0; i < table.GetUpperBound(0); i++)
{
int a = table[i, 0],
b = table[i, 1],
subtract = table[i, 2],
add = table[i, 3];

target.numericUpDown1.Value = a;
target.numericUpDown2.Value = b;

target.btnSubtract_Click(null, null);
int result = Convert.ToInt32(target.lblAnswer.Text);
Assert.AreEqual(subtract, result, String.Format(“Subtract {0} and {1}”, a, b));

target.btnAdd_Click(null, null);
result = Convert.ToInt32(target.lblAnswer.Text);
Assert.AreEqual(add, result, String.Format(“Add {0} and {1}”, a, b));
}
}

To run these tests, select Test->Run->All Tests in Solution from the main-menu in Visual Studio. The “Test Results” window in Visual Studio should show that all tests passed.

Summary

There’re multiple ways to go about automating UI testing. You could use an automated testing tool like Mercury Quick Test. However if you want to take things into your own hands and take advantage of greater control, you could write your tests using NUnit or MS-Test and make PInvoke calls to send messages to various controls in the UI of your application under test. You could use the SendKey API in Windows.Forms too.

However if you want to take advantage of knowledge of the internals of the application under test, we have to use Reflection to set properties of the controls, invoke event handlers, call other methods and then test whether this resulted in the changes that we expected. This makes the job extremely painful. I hope this article shows how much easier it is if we leverage Visual Studio Team System to generate accessors for us.

I don’t see why the technique described above cannot be used to test WPF and Silverlight applications as well.

Download
Click here to download the code accompanying this article.

Post

Automatic properties with custom logic – part 2

In .NET,Tech/Hacks on October 29, 2008 by Sid Tagged: , , ,

Let’s say we have a class called ShoppingCartItem. We’re going to concern ourselves with two properties here namely TaxID and Taxable. The business logic dictates that an item is definitely non-taxable if it has a tax-id of zero, otherwise it may or may not be taxable which is decided by some code situated outside the ShoppingCartItem class.

How would you write your ShoppingCartItem class?

Now – we cannot really take advantage of automatic properties over here.

public class ShoppingCartItem
{
public int TaxID { get; set; }
public bool Taxable { get; set; }
}

We really want the ShoppingCartItem to unset the Taxable flag when TaxID is zero. The setter for TaxID property seems to be the most obvious place to do that. But since we’re relying on the C# compiler to generate the getter/setter code we don’t really have control over that.

Of course, we have to fall back to the old way of doing it.

public class ShoppingCartItem
{
private int mTaxID;

public int TaxID
{
get
{
return this.mTaxID;
}
set
{
this.mTaxID = value;
if (this.mTaxID == 0)
this.Taxable = false;
}
}
public bool Taxable { get; set; }
}

That solves the problem we initially set out to solve but isn’t future proof. That’s because there’s nothing stopping a future programmer from adding new code in ShoppingCartItem class that directly saves values to mTaxID field instead of using the property setter. This could lead to Taxable being inconsistent with the value of TaxID. It would be better if we could somehow prevent direct setting of the backing field corresponding to the TaxID property even within the class.

Well, here’s an idea that leverages the lambda expression support in C# 3.0 to give us something that’s concise to write.

public class ShoppingCartItem
{
public PropertyValue TaxID;
public PropertyValue Taxable;

public ShoppingCartItem()
{
this.TaxID = new PropertyValue()
{
OnSet = value =>
{
if (value == 0)
this.Taxable.Value = false;
}

};
this.Taxable = new PropertyValue();
}
}

PropertyValue is the new class that I wrote. The idea is that you provide the code that should be executed when the TaxID is set, when initializing TaxID.

Here’s the code for the new class.

public class PropertyValue < T > : System.ComponentModel.INotifyPropertyChanged
{
#region Private fields

private Action mOnGet;
private Action mOnSet;
private T mValue;

#endregion

#region Constructors

public PropertyValue()
{
this.mValue = default(T);
}

public PropertyValue(T initialValue)
{
this.mValue = initialValue;
}

public PropertyValue(T initialValue, Action onGet, Action onSet)
{
this.mValue = initialValue;
this.mOnGet = onGet;
this.mOnSet = onSet;
}

#endregion

#region Properties

public Action OnGet
{
private get
{
return this.mOnGet;
}
set
{
if (this.mOnGet == null)
{
this.mOnGet = value;
}
else
{
throw new InvalidOperationException(“Getter can only be assigned once.”);
}
}
}

public Action OnSet
{
private get
{
return this.mOnSet;
}
set
{
if (this.mOnSet == null)
{
this.mOnSet = value;
}
else
{
throw new InvalidOperationException(“Setter can only be assigned once.”);
}
}
}

public T Value
{
get
{
if (this.mOnGet != null)
{
this.mOnGet(this.mValue);
}
return this.mValue;
}
set
{
this.mValue = value;
if (this.mOnSet != null)
{
this.mOnSet(this.mValue);
}
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(“Value”));
}
}
}

#endregion

#region INotifyPropertyChanged Members

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

#endregion

#region Overridden base class methods

public override string ToString()
{
if (this.mValue != null)
{
return this.mValue.ToString();
}
else
{
return base.ToString();
}
}

#endregion

}

While it does appear to solve the issue, I’m not quite satisfied. So let me end this by pointing out the things I don’t like in the implementation and ask for ideas:

  • It is wordier compared to the automatic property support in C# and requires you to know about lambda expressions. Here’s how I think it should have been:

    public class ShoppingCartItem
    {
    public int TaxID
    {
    get;
    set
    {
    if (value == 0)
    this.Taxable = false;
    }
    }
    public bool Taxable { get; set; }
    }

    This doesn’t work in C# 3.0 and generates a compiler error “ShoppingCartItem.TaxID.get’ must declare a body because it is not marked abstract, extern, or partial”.

  • Ideally, I should have been able to write the following which seems more succinct.

    public class ShoppingCartItem
    {
    public PropertyValue Taxable = new PropertyValue();
    public PropertyValue TaxID = new PropertyValue()
    {
    OnSet = value => {
    if (value == 0)
    Taxable = false;
    }

    };
    }

    But I cannot, because it generates a compiler error “A field initializer cannot reference the non-static field, method, or property”. This requires me to do the same thing inside the constructor which introduces an extra step.

What do you think?