Reputation: 185
I'm a newbie and I've never done unit-testing before.
I've made a console application that zips files and sends email. Now I want to do unit testing. But I'm not sure if my code is testable.
For example, I've a method called -
public static void readAndEmailCsvFiles(string filePath)
{
DirectoryInfo directory = new DirectoryInfo(filePath);
var files = directory.GetFiles("*.csv", SearchOption.AllDirectories);
var dirDate = string.Format("{0:yyyy-MM-dd HH-mm}", DateTime.Now);
bool isExists = System.IO.Directory.Exists(filePath + "\\" + "PROCESSED" + "\\" + dirDate);
if (!isExists)
{
System.IO.Directory.CreateDirectory(filePath + "\\" + "PROCESSED" + "\\" + dirDate);
}
try
{
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
foreach (var file in files)
{
Console.WriteLine("Processing File : " + file + "\n");
zip.AddFile(file.FullName, "");
zip.Save(Path.Combine(filePath, "PROCESSED", dirDate, file.Name) + ".zip");
sendEmail.SendMailMessage(Path.Combine(filePath, "PROCESSED", dirDate, file.Name) + ".zip");
}
}
foreach (var file in files)
{
File.Delete(file.FullName);
Console.WriteLine("");
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
How do I go about creating tests for the method above ?
Upvotes: 0
Views: 2473
Reputation: 428
Your class is taking ownership of too many responsibilities:
My first suggestion to you is to split these responsibilities among different services(classes), inject these services into your workflow, test each of the services on their own and finally test the workflow that uses all these services to get the job done
Examples:
One possible way to inject those services is like this:
public class ClassName
{
public ClassName(IEmailService emailService, IFileRespository fileRepository)
{
// You might want store the reference to these injected services
// and later use them to perform useful work
}
public void DoSomething()
{
// Do Something useful
}
}
Upvotes: 8
Reputation: 570
As the other answers below split the logic to two methods.
The Method1 can either return the zipped file or write it to a folder. Then you could unit test it like this:
The Method2 can also be unit tested:
The link says how to unit test a mail sending functionality. All we need to do is to configure the web.config inorder to unit test the mail functionality
Upvotes: 0
Reputation: 39248
I would consider moving the email sending part out of the current method. I would instead return the zipped file from the method and take care of the email sending as a second step after the method has completed. Testing sending and receiving emails is very difficult in unit tests.
There is a big dependency on the file system in this method, so your test is likely to be an integration test rather than a unit test, but I think that is ok in this case since you want to test various file operations. One advice though is to create any files your test depends on in the test itself. This is more reliable than assuming that a certain file exits.
Upvotes: 0