Testing IContentRepository

If you want to test against IContentRepository you have some different options.

1. Database

This is basically the same thing as when you’re running the site. In your test project you start up episerver in a console mode and each query/command is executed against the database in the same way it would have been if it had been done via a website.

This is the approach that is the closest to the real deal you’re going to get. It is slower (since it involves a database) and as far as I know there is no EPiServer 7 code available on how to get it to run in non-website way (here’s an example for EPiServer 6 R2).

2. Implementing IContentRepository

As the heading suggest this is method requires the daunting task of implementing the interface and make sure it works in the same manner as the database backed implementation provided by EPiServer. That is, if you in the test save a page as a child of the start page the said page would be returned on a subsequent call to GetChildren for the start page.

Since we don’t really care about the data once the tests are over this implementation is probably using some in-memory storage.

If you implement the interface correctly this is also very close to the real deal. The downside is that you have quite some code to implement for it to mimic DataFactory. But there are short cuts available, like only implementing the subset of feature that is relevant for you site. For example you may not have a site with multiple languages or don’t need versioning of content (in your tests that is).

3. Isolation framework

Using on of these isolation frameworks (Moq, FakeItEasy etc) you can in your test tell your IContentRepository how it should respond to various situations. For instance, when calling GetChildren with a PageReference with 5, then return these 5 pages.

When you want to test how your class interacts with the content repository it may work well. Like if you have tests for your schedule job that fetches data from somewhere and in the end creates a EPiServer page. You can then verify that Save was called with the expected parameters and that may be good enough. However when you actually care about the data, that is a page that is saved should be returned on subsequent loads it can quickly become messy.

Nitpicking

Yes, it’s entirely possible to implement the interface and back it with a isolation framework (but it’s not something I’d necessarily recommend).

  • Kod Exxon

    Your in-memory Content Repository is a gold nugget for unit testing EPiServer 7.x! Do you know if anyone’s actually using it? I got it to work just now (with trivial modifications) for unit testing an import program that creates pages in EPiServer, but there are some things I couldn’t quite figure out that had to be excluded from testing. I figured if others are using it they may have figured it out.

    • http://www.popkram.com Stefan Forsberg

      Hello! I know of one team that uses it (and from whom I shamefully stole the basis of it). SinceI haven’t had the chance to work with EPiServer myself for 1.5 years now I might not be able to help much with the things you’ve felt the need to exclude from testing. But if there are certain areas or if you have some more concrete examples I can at least forward them to a colleague of mine who might be able to share some insight?

      • Kod Exxon

        I don’t work with EPiServer either. I just thought it was a shame that they made many changes in 7.x to support unit testing but the puzzle pieces to actually make it work are still missing or scattered – one of them being the in-memory Content Repository. I was thinking more along the lines of putting together some kind of “unit testing for EPiServer 7.x framework” built on your in-memory Content Repository (and the stuff that comes with it) and making it available for anyone to improve upon and collaborate around. This would probably live best on EPiServer World.

        All the official and semi-official test implementations seem to use isolation/mocking, which has all the drawbacks you mention in this article, and they also seem to focus on testing the bits that don’t actually involve EPiServer. For truly test-driven development with EPiServer, that won’t suffice.

        The problems I had were mostly related to code using static EPiServer methods which don’t use the injected in-memory providers, but I’m sure a different coding style would remedy that (i.e. don’t use DataFactory.Instance or LanguageSelector.Autodetect; use the injected Content Repository and an injected Language Selector).