user2901683
user2901683

Reputation: 185

making code testable - unit testing

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

Answers (3)

Venu b
Venu b

Reputation: 428

Your class is taking ownership of too many responsibilities:

  • Logic that fetches the list of files
  • Logic that zips the files
  • Logic that sends email
  • Essentially this forms your workflow

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:

  • Have EmailService class that given a file sends out an email
  • Have FileRepository class that fetches a list of files given a path
    etc

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

shajivk
shajivk

Reputation: 570

As the other answers below split the logic to two methods.

  • Method1: To create the Gzip
  • Method2: TO mail the file.

The Method1 can either return the zipped file or write it to a folder. Then you could unit test it like this:

  • Test1 Check whether file exists
  • Test2 Check whether file is in the Correct Format (try to unzip with the same logic inside the unit test method)

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

TGH
TGH

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

Related Questions