Wednesday, September 16, 2009

A Small Unit Testing Gem

Since I started writing unit tests for my code, I had this question in mind. Let's say I have a project that is a class library. I have a class in that library and this class has some internal methods. Like this:

public class MyClass
{
public void MyPublicMethod
{
int k
// do something ...
int z = MyInternalMethod(k);
// do something else ...
}

internal int MyInternalMethod(int i)
{
// do something ...
}
}

Now I want to write unit tests for these methods. I would create a "UnitTests" project, reference the nunit.framework from it and write something like this:

[TestFixture]
public class UnitTests
{
private MyClass myClass;

[SetUp]
public void SetupTest
{
myClass = new MyClass();
}

[Test]
public void TestMyInternalMethod
{
int z = 100;
int k = myClass.MyInternalMethod(z); //CAN NOT DO THIS!
Assert.AreEqual(k, 100000);
}

[TearDown]
public void TearDown
{
myClass = null;
}
}

Of course, I can not do this, because of the MyInternalMethod scope. Today the StackOverflow guys pointed me to this little gem which is very helpful.

.Net Gem - How to Unit Test Internal Methods

Here's the short summary:

Go to the project that contains MyClass. Locate the AssemblyInfo.cs file. Add the following line to it:

[assembly: InternalsVisibleTo("UnitTests")]

Done!

by . Also posted on my website

Thursday, September 10, 2009

Thread Pooling

I have to take care of multiple printers in my application. The "Print Manager" receives a list of jobs which is basically an XML file of a simple structure - a number of PrintJob nodes. Each print job has a printer assigned to it.

The Print Manager has to send each job to the appropriate printer, and also notify the sender of the XML of the completion or failure of each job. I'm sure tasks like these are common but somehow could not find good suggestions on implementing this one. I found a Miscellaneous Utility Library though (written by Jon Skeet himself by the way) which implemented a class called "CustomThreadPool", which allows creating multiple thread pools in a .NET application.

So, my approach so far is as follows: Get a print job. If a pool exists for this printer, place the job in a thread in the pool. Otherwise, create a pool and place the job in a thread in this pool. Get next job.

Here is how it looks like so far:

private List _printerThreads = new List();

delegate Errors ThreadMethod(PrintJob job);

private Errors InsertThread(PrintJob job)
{
ProcessSinglePrintJob(job);
}

// stuff ...

public void ProcessPrintJobs()
{
if (_printJobs != null)
{
foreach (PrintJob printJob in _printJobs)
{
if(String.IsNullOrEmpty(printJob.PrinterName))
{
printJob.JobResult = Errors.PrinterNameNotSpecified;
}
else if (String.IsNullOrEmpty(printJob.ReaderName) && printJob.IsEncodeSmartCard)
{
printJob.JobResult = Errors.SmartCardReaderNameNotSpecified;
}
else
{
CustomThreadPool pool = _printerThreads.Find(delegate(CustomThreadPool test)
{
return test.Name == printJob.PrinterName;
});

if (pool == null)
{
pool = new CustomThreadPool(printJob.PrinterName);
}

ThreadMethod method = new ThreadMethod(InsertThread);

pool.AddWorkItem(method, printJob);
}
}
}
}

I don't have extensive experience with multithreading so this solution might not even work or it may be too complex for the task. I'll run some tests soon anyway with the actual printers.

by . Also posted on my website

Tuesday, September 1, 2009

Studying Interprocess Communication

Today I had to solve a simple problem. Let's say there are two processes running on one computer. The first service polls a database for print jobs. As soon as a job is found, a second service has to send the job to the printer. So, effectively, I have to pass some data from one local service to another.

The first, "amateurish" solution that came to my mind was to write data to a text file by the "polling" service and read from that file by "printing" service. But I thought that the task like this should be a standard one and looked around. Here's one of the examples I found:

.NET 3.5 Adds Named Pipes Support

Here's the probably the simplest working example: First, I need to create two windows services. I add a timer to each service. I also add an event log to each of the services to be able to check if they work. One of the services will be a "server". Here's what goes into it's timer_Elapsed:

using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("testPipe", PipeDirection.Out))
{
pipeServer.WaitForConnection();

try
{
using (StreamWriter sw = new StreamWriter(pipeServer))
{
sw.AutoFlush = true;
string dt = DateTime.Now.ToString();
sw.WriteLine(dt);
pollingEventLog.WriteEntry(dt + " written by the server");
}
}
catch (IOException ex)
{
pollingEventLog.WriteEntry(ex.Message);
}
}

The other service will be a "client". Here's what goes into it's timer_Elapsed:

using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "testPipe", PipeDirection.In))
{
pipeClient.Connect();
using (StreamReader sr = new StreamReader(pipeClient))
{
string temp;
while ((temp = sr.ReadLine()) != null)
{
printManagerEventLog.WriteEntry(temp + " read by the client");
}
}
}

This is it - after both services are compiled, installed and started, their cooperation can be observed through the Event Log. Total time including googling, understanding the concept and implementing the working example - under 30 minutes.

by . Also posted on my website