Try our conversational search powered by Generative AI!

Niklas Melinder
Nov 29, 2010
  6450
(3 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

John Parr
John Parr Nov 29, 2010 09:21 AM

'Hassle' often means I can't do it easily, quickly and cheaply as I need to or would like.

The whole 'how much effort do we test mentality' can be both political, economic and ideological and is often decided and imposed on us by others.

So let's not blame EPiServer because the whole point of testing the view or presentation in web forms it a whole topic by itself.

Joel Abrahamsson
Joel Abrahamsson Nov 29, 2010 10:13 AM

John, I think Niklas was referring to the EPiServer API. And when it comes to that I actually think we should blame EPiServer :-)
After all it is their API that forces us to either rely on concrete implementations instead of abstractions and thereby violating a bunch of design principles or to rely on third party abstractions of their API, ie EPiAbstractions.
Luckily they are working to fix a lot of those problems in the next major version by creating IDataFactory, (hopefully) making members of PageData virtual etc. And they should definitely be applauded for having made the DDS well designed and testable (kudos Paul!).

Niklas Melinder
Niklas Melinder Nov 29, 2010 12:27 PM

Testing code using the EPiServer API is a hassle. Testing code using WebForms is to, but that is a whole other story.

The point of this post was to show how easy it can be to test code when the framework you are using supports it.

smithsson68@gmail.com
smithsson68@gmail.com Dec 1, 2010 02:50 PM

Thanks Joel for the kudos but obviously DDS was a team effort :-)

Matthew Howard
Matthew Howard Sep 4, 2012 03:24 PM

How do you delete an item from a dynamicdatastore and edit an existing item?

Please login to comment.
Latest blogs
Optimizely Search and Navigation - Part 2 - Filter Tips

Introduction Continuing from Part 1 – Search Tips , today I will share the next part – filter tips. The platform versions used for this article are...

Binh Nguyen Thi | Jul 1, 2024

Integrating HubSpot CRM without the MA Connector

Have HubSpot CRM? Want to push user data into it from Optimizely? Don’t have any personalisation requirements with that data? Don’t want to pay $80...

Matt Pallatt | Jun 27, 2024

Keeping the website secure by updating external packages

Did you see the latest warning from Optimizely to update this package with a critical security warning? https://world.optimizely.com/documentation/...

Daniel Ovaska | Jun 27, 2024

Optimizely CMS image anonymization now available for Linux!

The famous image anonymization add-on for Optimizely CMS, with at least 5 downloads, is now finally available for use on Linux. Supports simultaneo...

Tomas Hensrud Gulla | Jun 25, 2024 | Syndicated blog