2

Has anyone been able to get the combination of AutoFixure, FakeDb and NUnit3 to work?

I am unable to retrieve an item I have added to the database (using example from FakeDb AutoFixture wiki page); the test does not pass:

<package id="Sitecore.FakeDb" version="1.7.4" targetFramework="net472" />
<package id="Sitecore.FakeDb.AutoFixture" version="1.7.4" targetFramework="net472" />
<package id="AutoFixture" version="3.51.0" targetFramework="net472" />
<package id="AutoFixture.NUnit3" version="3.51.0" targetFramework="net472" />
<package id="NUnit" version="3.11.0" targetFramework="net472" />

[Test]
[AutoDbData]
public void AddContentDbItem(Db db, DbItem item)
{
    db.Add(item);
    var newItem = db.GetItem(item.ID);

    newItem.Should().NotBe(null);
}

However, if I bypass the NUnit attribute integration with AutoFixure, the test passes (but this loses a lot of the benefits I wanted when using AutoFixture):

[Test]
public void AddContentDbItem()
{
    var fixture = new Fixture()
        .Customize(new AutoDbCustomization())
        .Customize(new AutoContentItemCustomization());

    var item = fixture.Create<DbItem>();
    var db = fixture.Create<Db>();

    db.Add(item);
    var newItem = db.GetItem(item.ID);

    newItem.Should().NotBe(null);
}

This suggest to me that the issue is with the interaction between Sitecore.FakeDb and Autofixture.NUnit3 (rather then NUnit itself).

Also, if I change the testing framework to XUnit, the test will pass:

<package id="AutoFixture.Xunit2" version="3.51.0" targetFramework="net472" />
<package id="xunit.core" version="2.4.1" targetFramework="net472" />

[Theory]
[AutoDbData]
public void AddContentDbItem(Db db, DbItem item)
{
    db.Add(item);
    var newItem = db.GetItem(item.ID);

    newItem.Should().NotBe(null);
}

Has anyone been able to get the combination of AutoFixure, FakeDb and NUnit3 to work? NUnit has been the preferred testing framework in my company for years and there is reluctance to change just to solve this issue.

  • "if I change the testing framework to XUnit, the test will pass" - sounds like a bug – Serhii Shushliapin Feb 28 at 11:45
  • 2
    FakeDB and NUnit dont mix that well.. also had issues with that combination. Stick with XUnit ;) – Gatogordo Feb 28 at 12:10
  • I agree to this i had spend almost 1 week of work to make FakeDb work with Nunits and it didn't worked. We had a requirement to right test cases for Solr Functionality which required Fake Index and microsoft confirmed that this is not possible with Nunits – Alivor Tikos Mar 2 at 17:15
  • Thank you all for your comments; from your experiences it definitely seems like there is a negative interaction between FakeDb and AutoFixture.NUnit. I have been able to convince other to switch to XUnit to move forward with this project. – Mark Smith Mar 4 at 9:22
2

I will start my answer with a question, why do you need to use FakeDB?

Even though the idea of FakeDB is great in theory, it inevitably causes more issues than it solves, in my opinion, when testing units in your code, it's another story when you are carrying out integration tests, but then the argument would be why not manipulate a real Sitecore database.

What I would suggest that you consider is not test Sitecore is doing its job and only test business logic you are writing. You could use a pattern like Template Method to help write logic that does not know about Sitecore. You would completely control and mock these classes and then create implementations that can talk to Sitecore. These abstract classes would only use POCOs to build up functionality using TDD, mocking to your heart’s content, and then all the implementation does is map Sitecore items to those POCOs.

Unit testing aims to test a unit, or as I think of it test a single logical pathway through your code, the best way to do this is using contrived implementations of contracts. As soon as you introduce FakeDB you no longer have a single logical pathway, as really Sitecore code is being executed to carry out your test along with FakeDb code, effectively making the unit part of the unit testing moot. If you believe that Sitecore is not functioning as expected open up a support request as testing Sitecore is not your responsibility and only increases the about of testing code you must maintain.

I feel that when tightly coupling your business logic code to Sitecore you end up with code that is less maintainable and reusable. Be careful with trusting unit testing as it can quickly become a false economy if you are creating tests just to get 100% coverage. The coverage metric that is important is, am I testing all logical pathways? Oh and never change unit tests just to satisfy the compiler, this makes your tests rot. Your test are the most important part of a solution so treat them as such.

Sorry for the long answer, I did not think I had that much to say and think I will blog about this with an example of the approach I am describing.

  • Thank you for your thoughts. I look forward to your blog, and would appreciate you linking to it from here once it is available. When I first started working with Sitecore I looked into abstracting away all reference to Sitecore, but it was too steep a learning curve and the project needed to move forward swiftly. With regard to FakeDb, it facilitates testing core logical pathways on code that was not written using TDD methodology. We are not using it to test if "Sitecore is doing its job", but rather when given a particular context does the code behave as expected. – Mark Smith Mar 4 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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