2

I am pretty new to creating unit test for function, and are currently given the task to create some unit test for this class.

namespace Sandbox.Processors
{
    using Sitecore.Data.Items;
    using Sitecore.Pipelines.HttpRequest;
    using System;
    using System.Web;

    public class RobotsTxtProcessor : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
             HttpContext context = HttpContext.Current;

             if (context == null)
             {
                 return;
             }

             string requestUrl = context.Request.Url.ToString();

             if (string.IsNullOrEmpty(requestUrl) || !requestUrl.ToLower().EndsWith("robots.txt"))
             {
                 return;
             }

             string robotsTxtContent = @"User-agent: *"
                                       + Environment.NewLine +
                                       "Disallow: /sitecore";

             if (Sitecore.Context.Site != null && Sitecore.Context.Database != null)
             {
                  Item homeNode = Sitecore.Context.Database.GetItem(Sitecore.Context.Site.StartPath);

                  if (homeNode != null)
                  {
                      if ((homeNode.Fields["Site Robots TXT"] != null) &&
                          (!string.IsNullOrEmpty(homeNode.Fields["Site Robots TXT"].Value)))
                      {
                          robotsTxtContent = homeNode.Fields["Site Robots TXT"].Value;
                      }
                  }
             }

             context.Response.ContentType = "text/plain";
             context.Response.Write(robotsTxtContent);
             context.Response.End();
         }
    }
}

The process function is pretty neat, nicely seperated into if statements, which can be individually tested, but the problem here is that the function doesn't return anything so there is nothing to catch...

How do I go by creating unit test for this kind of functions?

Jan Bluemink
  • 3,467
  • 1
  • 21
  • 35
I am not Fat
  • 283
  • 11
  • 36
  • 2
    The method does a lot of things, which one do you want to test? Most lines of code within this method would require either a) lots of mocking to the extent that you wouldn't be testing anything, or b) an integration test as most of this method is about the interactions not the code. – Fenton Nov 13 '18 at 13:58
  • just the if statements, that they are being triggered. – I am not Fat Nov 13 '18 at 14:04
  • For the Sitecore Context, see FakeDb https://github.com/sergeyshushlyapin/Sitecore.FakeDb – Jan Bluemink Nov 13 '18 at 21:37
  • @IamnotFat - you have practical answers below, but if you haven't come across the difference between Classical TDD and London School TDD you will find it beneficial in your case. – Fenton Nov 14 '18 at 08:55
  • If your goal is unit testing, I would recommend breaking this method up into more distinct pieces that accomplish specific goals. For example, it seems like you have a block responsible for retrieving robotsTxtContent from an item. A method like "GetSiteRobotsText(Database db, Site site)" might help you isolate some of your unit testing and make it easier to have less reliance on the Site and Database context – Jay S Nov 15 '18 at 13:20

1 Answers1

2

You would need to create a mock HTTPContext and inject it into the method for the test. (You probably need to mock quite a few other objects too, since the method has several dependencies.)

Then, after the method has run, assert that the the response in the context is as you want it.

See details here: Mock HttpContext.Current in Test Init Method

Jasper Kent
  • 3,546
  • 15
  • 21
  • hmm.. What about the input arguments? for the process function? I guess i pretty blunt on how to set it up.. – I am not Fat Nov 14 '18 at 09:27
  • The Process() function is the thing you're testing, so you don't want to mock that. I'm not sure about HttpRequestArgs, since it's not a .NET type. If, as the name suggests, it's a simple data store, you probably won't need to mock it. If it's something more complicated, you may have to. – Jasper Kent Nov 14 '18 at 11:43