0

I am trying to set up a simple test project to initially assert that my local C# models correspond to my Sitecore templates. The Item retrieval is successful using Database.GetItem(itemPath) and I can inspect the item by debugging the test and can confirm that all Item.Fields are present and contain the correct data. The field Item.HasClones however contains an error:

'item.HasClones' threw an exception of type 'System.NullReferenceException'

I have debugged the same Item when running the live application and then HasClones is just false so this only happens when getting the item in the test project.

When I attempt to read text from one of the fields using the FieldRenderer.Render method it results in a System.NullReferenceException. I can access the text in the same field using item.Fields["Title"].Value.ToString(); without issue though.

I have tried getting around security using the SecurityDisabler in case HasClones was somehow protected but no luck. I am not sure these two errors are connected but I have no idea how to confirm it. Have I missed something in the Context configuration or something like that? The same code runs fine in the main project (where Item is accessed using RenderingContext.Current.Rendering.Item instead of with GetItem) so does something else need initiating that I have missed?

Test code:

    [SetUp]
    public void SetUp()
    {
        State.HttpRuntime.AppDomainAppPath = TestContext.CurrentContext.TestDirectory;
        Context.SetLanguage(Language.Parse("sv-SE"), true);

        this.masterDb = Factory.GetDatabase("master");
    }

    [Test]
    public void GetSomeBlockData_GetDataFromSitecore()
    {
        Item item;
        string titleText;

        using (new SecurityDisabler())
        {
            item = masterDb.GetItem("/sitecore/content/TestBlock");

            bool hasClones = item.HasClones; // System.NullReferenceException: Object reference not set to an instance of an object.


            titleTextOk = item.Fields["Title"].Value.ToString(); // This works fine
            titleTextBroken = FieldRenderer.Render(item, "Title"); // System.NullReferenceException : Object reference not set to an instance of an object.
        }
    }

I am running: Sitecore.NET 8.2.170407, the project is using .NET 4.5.2. Testing framework is Nunit.

All the best //VA

EDIT:

I have investigated further and found that the issue with the FieldRenderer.Render is that in the Render method it uses the class RenderFieldArgs which in turn tries to check Context.Site.DisableWebEditEditing when initiated. Context.Site is null so the method fails. I have tried to get Context working, mostly by following this guide but I can't get it working.

5
  • Hi, Have you tried Sitecore.FakeDb to mock your Sitecore items? github.com/sshushliapin/Sitecore.FakeDb Commented Jan 14, 2021 at 16:51
  • @ÁrvaiMihály yes I have looked at FakeDb and might be using it for some tests as well but in this case I want to confirm what is actually in the Sitecore DB. By using FakeDb I feel that I would just be testing that my constructed FakeDb items were correct, not my real Sitecore items :)
    – Viktor
    Commented Jan 14, 2021 at 18:31
  • You don't wanna do this. Just saying. Every time you make a change in your Sitecore structure, you need to make a change in your code structure, which will necessitate a change in your "unit" test. What good is a test then? :D
    – Mark Cassidy
    Commented Jan 14, 2021 at 20:57
  • @MarkCassidy that is exactly why I want to do this, because there are several people working on this project. If one of them changes the Sitecore structure without fixing the code structure I want to find that out when running the tests, not when the code is deployed and no text shows up (or worse) because someone decided to change a field name in Sitecore. So the tests will make sure that Sitecore and code structure are in sync, just like if we were testing an integration with an API for example.
    – Viktor
    Commented Jan 15, 2021 at 8:31
  • Personally I think a unit test should not have any dependency on external resources. If you still want to validate item structure/item fields, I would go with some integration tests, querying items from a Sitecore instance via Item WebApi. Commented Jan 15, 2021 at 14:12

1 Answer 1

0

I have found a solution to the issue, the problem in my case was that I had not set a site using Context.SetActiveSite("website");.

The following code works in my case:

using NUnit.Framework;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Globalization;

namespace Testclass
{
    [TestFixture]
    public class MyTests
    {
        private Database masterDb;

        [SetUp]
        public void SetUp()
        {
            State.HttpRuntime.AppDomainAppPath = TestContext.CurrentContext.TestDirectory;
            Context.SetActiveSite("website");
            Context.SetLanguage(Language.Parse("sv-SE"), true);

            this.masterDb = Factory.GetDatabase("master");
        }

        [Test]
        public void GetItemDataFromSitecore()
        {
            Item item = masterDb.GetItem("/sitecore/Content/TestItem");
            MyItemModel data = new MyItemRepository().GetData(item);

            Assert.That(data.Title.ToString(), Is.EqualTo("My Title"));
        }
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.