0
votes

I am trying to run a unit test against a FakeDB setup using NUnit and Moq. The sitecore query is being abstracted through an interface which I'm Mocking. When I intially call the query it correctly creates the items with Field values. When the query results are used by the test method calling the repository - the field values all of the sudden go away.

I shortened the test and put it into this file. It has the bare minimum to run:

using System;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.FakeDb;

namespace NYL.UnitTests.FakeDB
{
    [TestFixture]
    public class FakeDbFieldValueTest
    {
        private readonly Mock<IRepository> _repo = new Mock<IRepository>();
        private readonly ID _someItemTemplateId = ID.NewID;

        [SetUp]
        public void SetUp()
        {
            //database = FakeDatabase();
            _repo.Setup(m => m.GetListOfItems()).Returns(Mock_GetListOfItems());
        }

        [Test]
        public void Test_FakeDbFieldRetention()
        {
            // arrange
            var items = _repo.Object.GetListOfItems();

            // assert
            items.Should().NotBeNull();
            items.Should().HaveCount(3);

            foreach (var item in items)
            {
                // Fields are null after passed back through mock
                item.Fields["Some Field"].Should().NotBeNull();
                item["Some Field"].Should().NotBeNullOrEmpty();
            }
        }

        private IDisposable FakeDatabase()
        {
            return new Db
            {
                new DbItem("Home")
                {
                    new DbItem("First Child", ID.NewID, _someItemTemplateId)
                    {
                        {"Some Field", "Value One"}
                    },
                    new DbItem("Second Child", ID.NewID, _someItemTemplateId)
                    {
                        {"Some Field", "Value Two"}
                    },
                    new DbItem("Third Child", ID.NewID, _someItemTemplateId)
                    {
                        {"Some Field", "Value Three"}
                    }
                }
            };
        }

        private Item[] Mock_GetListOfItems()
        {
            using (FakeDatabase())
            {
                var query = string.Format("fast:/sitecore/content/Home//*[@@templateid = '{0}']", _someItemTemplateId);
                var items = Sitecore.Context.Database.SelectItems(query);

                foreach (var item in items)
                {
                    // Field Values render fine at creation
                    item.Fields["Some Field"].Should().NotBeNull();
                    item["Some Field"].Should().NotBeNullOrEmpty();
                }

                return items;
            }
        }
    }

    public interface IRepository
    {
        Item[] GetListOfItems();
    }
}

The method Test_FakeDbFieldRetention fails spectacularly with the fields being completely removed. In my comments you can see where the fields are found, so they are being set initially. However when passed through the repository interface they just disappear.

Can anyone help spot this error?

3
why you doing this much of complex.Create one class with some properties and create one list of that class pass that list of class in return statement after that call the service .it will be mock.Pankaj Gupta
This question doesn't make a lot of sense from a unit testing point of view? What are you trying to test? It never appears to call any logic? there is no point unit testing a DB. All your testing is that the DB is in x state (which you already know) and once that state changes the unit test doesn't achieve anything. Unit tests should replicate a state to test logic.Liam

3 Answers

2
votes

Have you tried adding a DbTemplate for _someItemTemplateId? I'm not sure how FakeDb implements it but, with the sql provider, if the fields can't be found on the template the values are not saved.

0
votes

I always do my Asserts inside the using statement when using FakeDb. You should check that the IDisposable is not tearing down you FakeDb items.

0
votes

Hey you can checkout template inheritance section, and ensure your getting the item properly.