Debugging a failing unit-test which interacts with RavenDB

RavenDB, English posts Comments (1)

This week I'm working with Particular Software of NServiceBus fame. There's a shiny new platform for designing, managing and debugging distributed systems coming up and while doing some work on it I hit the following failing test. The documentStore is an EmbeddableDocumentStore which was properly initialized, and the index used was registered properly. Nevertheless, the first Assert is failing. Can you figure out what's wrong?

    [Test]
    public void Order_by_critical_time()
    {
        session.Store(new ProcessedMessage
        {
            Id = "1",
            MessageMetadata = new Dictionary<string, object> { { "CriticalTime", TimeSpan.FromSeconds(10).Milliseconds} }
        });

        session.Store(new ProcessedMessage
        {
            Id = "2",
            MessageMetadata = new Dictionary<string, object> { { "CriticalTime", TimeSpan.FromSeconds(20).Milliseconds} }
        });
        session.SaveChanges();

        var firstByCriticalTime = session.Query<MessagesViewIndex.SortAndFilterOptions, MessagesViewIndex>()
              .OrderBy(x => x.CriticalTime)
              .Customize(x => x.WaitForNonStaleResults())
              .AsProjection<ProcessedMessage>()
              .First();
        Assert.AreEqual("1", firstByCriticalTime.Id);

        var firstByCriticalTimeDesc = session.Query<MessagesViewIndex.SortAndFilterOptions, MessagesViewIndex>()
              .OrderByDescending(x => x.CriticalTime)
              .AsProjection<ProcessedMessage>()
              .First();
        Assert.AreEqual("2", firstByCriticalTimeDesc.Id);
    }

I wasn't able to figure out what was going wrong. Results were just coming back out of order, and I couldn't tell if it was something bad with the index, or the documents inserted by the test were faulty?

Luckily, there is an easy way out - and it's exactly what I used. You can suspend a unit-test while running it in Debug by calling WaitForUserToContinueTheTest(documentStore); - this method as well as some other helper methods are available in this nuget package, or in the source form here. Just add it to your unit testing classes and call it when needed.

This method is super useful - it will suspend the test and open up the management studio of the embedded database instance used by the test, so you could go through it and look at the documents it has, the index definitions, execute queries against it and so on.

So I added those 2 lines to my test, just before the first query:

    WaitForIndexing(documentStore);
    WaitForUserToContinueTheTest(documentStore);

And executed the test again. Now the Management Studio opened up, and the culprit was immediately visible by having a quick look at the documents in the document store - the CriticalTime property was 0 on both documents, not what I was expecting. I've spent too much time in the Java land apparently, and forgot that I had to use the Ticks property of the TimeSpan class to get the actual time value as a long.

Making this change made the test green again, and off I went to working on the next feature. I sure have saved myself quite a lot of time and hair.

Comments

  • Tomek

    all sweet but why do you call it a unit test? as far as I undestood you hit a real database, righ?

    • Itamar Syn-Hershko

      Just a code name for tests. You are right you'll have this scenario only in Integration or Acceptance tests.

Leave a Comment