A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More


Nov 29, 2010
  4949
(0 votes)

Testable code using Dynamic Data Store

There is some talk about how testing using EPiServer is a hassle. And it is for many reasons. There are exceptions though, and Dynamic Data Store is one of them. In contrast to EPiServer.DataFactory for example, which is a sealed class, both DynamicDataStoreFactory and DynamicDataStore are abstract classes. This is good news from a testing perspective since we can override their behavior. Good work team!

The example I´m gonna show is from the EPiSocial plugin I´ve been working on, which uses DDS. This is from the CommentRepository.

Setup

First some setup changes. Instead of using DynamicDataStoreFactory.Instance to get the store:

   1: public DynamicDataStoreCommentRepository()
   2: {
   3:     this.commentStore = DynamicDataStoreFactory.Instance.GetStore(typeof(PageComment));
   4: }

We can instead take a dependency to the abstract class DynamicDataStoreFactory:

   1: public DynamicDataStoreCommentRepository(DynamicDataStoreFactory dynamicDataStoreFactory)
   2: {
   3:     this.commentStore = dynamicDataStoreFactory.GetStore(typeof(PageComment));
   4: }

With this small change we´ll be able to test the code in the CommentRepository.

Let´s use the GetLatestComments method as the scenario for this:

   1: public IEnumerable<PageComment> GetLatestComments(int count, string pageLanguage)
   2: {
   3:     return this.commentStore.Items<PageComment>()
   4:         .Where(c => c.PageLanguage == pageLanguage)
   5:         .OrderByDescending(c => c.Created)                
   6:         .Take(count);
   7: }

Testing

To test that method we have to setup a fake data store to test against. I did this using Moq. Let´s say that we want to test that the method returns only pages in the language that we provide. It could look something like this:

   1: [Test]
   2: public void Given_a_store_with_comments_for_multiple_pages_when_getting_latest_comments_then_only_comments_for_provided_page_language_is_returned()
   3: {
   4:     // Arrange
   5:     var pageCommentList = new List<PageComment>();
   6:     pageCommentList.Add(new PageComment { PageId = 1, PageLanguage = "sv" });            
   7:     pageCommentList.Add(new PageComment { PageId = 2, PageLanguage = "en" });
   8:  
   9:     IOrderedQueryable<PageComment> queryableItemList = new EnumerableQuery<PageComment>(pageCommentList );
  10:     var dataStoreFactoryMock = new Mock<DynamicDataStoreFactory>();
  11:     var dataStoreMock = new Mock<DynamicDataStore>(null);
  12:  
  13:     dataStoreFactoryMock
  14:         .Setup(x => x.GetStore(typeof(PageComment)))
  15:         .Returns(dataStoreMock.Object);
  16:  
  17:     dataStoreMock
  18:          .Setup(x => x.Items<PageComment>())
  19:          .Returns(queryableItemList);
  20:  
  21:     var ddsCommentRepository = new DynamicDataStoreCommentRepository(dataStoreFactoryMock.Object);
  22:  
  23:     // Act
  24:     var latestComments = ddsCommentRepository.GetLatestComments(3, "sv");
  25:  
  26:     // Assert
  27:     Assert.That(latestComments, Contains.Item(pageCommentList[0]));
  28:     Assert.That(latestComments, !Contains.Item(pageCommentList[1]));      
  29: }

That´s pretty much it, not that hard really. I think this shows how easy testing can be if it is somewhat supported by the framework. Hoping for more of this in upcoming EPiServer versions.

Nov 29, 2010

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP: Learning Optimizely Just Got Easier: Introducing the Optimizely Learning Centre

On the back of my last post about the Opti Graph Learning Centre, I am now happy to announce a revamped interactive learning platform that makes...

Graham Carr | Jan 31, 2026

Scheduled job for deleting content types and all related content

In my previous blog post which was about getting an overview of your sites content https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/sche...

Per Nergård (MVP) | Jan 30, 2026

Working With Applications in Optimizely CMS 13

💡 Note:  The following content has been written based on Optimizely CMS 13 Preview 2 and may not accurately reflect the final release version. As...

Mark Stott | Jan 30, 2026

Experimentation at Speed Using Optimizely Opal and Web Experimentation

If you are working in experimentation, you will know that speed matters. The quicker you can go from idea to implementation, the faster you can...

Minesh Shah (Netcel) | Jan 30, 2026