1

We've been testing our Sitecore code with the codeflood but wanted to do more to automate our tests on local and CI builds. I've been following the solution laid out by Mike Edwards on how to use NUNIT to run Sitecore tests -

Later, Dan Solovay had posted some thoughts on how to improve that -

So far this works great in a visual studio build. Config is copied from the Sitecore web site to the test project and NUNIT can execute tests that retrieve items from Sitecore, all without a context.

My problem - we make use of Glass Mapper for things like this:

Database database = global::Sitecore.Configuration.Factory.GetDatabase("master");
ISitecoreService SitecoreService = new SitecoreService(database);

var catalogItem = database.GetItem([guid to our item]);
Assert.IsNotNull(catalogItem);

var catalog = SitecoreService.CreateType<ProductCatalog>(catalogItem, true, true);
Assert.NotNull(catalog);
Assert other things on our ProductCatalog class...

The problem seems to be that Glass Mapper's SitecoreService constructor needs a context and if it doesn't get one, it uses "Default". Since we're executing in NUNIT, there isn't a context and the creation of Sitecore Service fails.

I doubt there is a clear cut answer that fixes this but I'd be interested in anyone's thoughts.

Maybe the use of Glass Mapper in the test just isn't possible without the Sitecore context. On the other hand, I am by no means a Glass expert - maybe there is a different way to go about mapping my class in the test?

Jason Booth
  • 185
  • 1
  • 10

1 Answers1

2

The Glass SitecoreService and SitecoreContext both have interfaces, your tests should mock this interfaces using a mock framework like NSubstitute or MOQ. For example using NSubstitute:

var product = new ProductCatalog();  
product.Title = "Hello world";  

ISitecoreService service = Substitute.For<ISitecoreService();
service.GetItem([Guid]).Returns(product);

var result = service.GetItem([Guid]);

Assert.AreEqual("Hello world", result.Title);

Your test above seems to be testing if Glass returns an item rather than testing the business logic of your application. You should avoid these sorts of tests.

Michael Edwards
  • 6,308
  • 6
  • 44
  • 75
  • Thanks! I'll give that a shot - that makes sense. Regarding testing Glass vs our business logic, I hear you. The test is actually longer and tests the logic of ProductCatalog. It would have been clear with a larger code sample. Thank you! – Jason Booth Jul 10 '14 at 12:42
  • I thought I got it but I was wrong... If I mock Sitecore service, I can't actually map an item from Sitecore. If I can't map it, I can't test the business logic in ProductCatalog. I was thinking I could programmatically set properties on product (my ProductCatalog instance) but the result of service.GetItem is NSubstitute.Core.ConfiguredCall where I was expecting a ProductCatalog. Am I just thinking about this all wrong? – Jason Booth Jul 10 '14 at 20:17
  • 1
    You shouldn't want to pull an item from Sitecore in your unit test as this would then become an integration test. Assign the values you expect to pull from sitecore to the instance of the ProductCatalog class in your unit test. I have updated the example above to show this. – Michael Edwards Jul 11 '14 at 09:19
  • Yes; got it! I was trying this yesterday but was missing var result = service.GetItem([Guid]); I was trying to set result equal to service.GetItem([Guid]).Returns(product). Now comes the big task of taking all my TDS/Sitecore test data and moving it to manageable setup and teardown routines. Thanks @Michael Edwards. – Jason Booth Jul 11 '14 at 14:08