A guide to getting started with unit testing in Umbraco
These examples inspire unit testing in Umbraco with Umbraco 9.x, 10.x, 11.x and 12.x, using NUnit, Moq, and AutoFixture. There are many ways of testing Umbraco and there’s no right or wrong way.
When testing components in Umbraco, such as controllers, helpers, services etc. these components often require that you provide a couple of dependencies in your classes using dependency injection. This is because a lot of magic happens “under the hood” of Umbraco and these dependencies are needed for that magic to happen.
Writing Unit Tests increases awareness of underlying dependencies, enhancing your skills as an Umbraco developer.
Mocking
These tests follows an approach thats based on isolating your tests from Umbraco and mock as much of Umbraco’s dependencies as possible. Think of it like you’re not testing Umbraco, you’re testing how your implementation code interacts with Umbraco’s behavior.
Once you become familiar with these underlying dependencies, you may consider replacing them with actual implementations. This can lean towards integration or end-to-end testing, but the decision is yours. Again these examples should be a source of inspiration and the quickest way to get started with Unit Testing.
If you are new to mocking you can read more on this topic here or use the Moq Quickstart guide. For more inspiration and other ways of how to write tests in Umbraco there's a blogpost from HQ member Bjarke Berg about Automated Testing.
public class PageSurfaceController : SurfaceController
{
public PageSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) { }
[HttpPost]
public IActionResult Submit()
{
return Content("H5YR!");
}
}
public class PageSurfaceControllerTests
{
private PageSurfaceController controller;
[SetUp]
public void SetUp()
{
this.controller = new PageSurfaceController(Mock.Of<IUmbracoContextAccessor>(), Mock.Of<IUmbracoDatabaseFactory>(), ServiceContext.CreatePartial(), AppCaches.NoCache, Mock.Of<IProfilingLogger>(), Mock.Of<IPublishedUrlProvider>());
}
[Test]
public void When_SubmitAction_ThenResultIsIsAssignableFromContentResult()
{
var result = this.controller.Submit();
Assert.IsAssignableFrom<ContentResult>(result);
}
[Test]
public void When_SubmitAction_Then_ExpectHelloWorld()
{
var result = (ContentResult)this.controller.Submit();
Assert.AreEqual("H5YR!", result.Content);
}
}
ServiceContext.CreatePartial() has optional parameters, and by naming them you only need to mock the dependencies that you need, for example: ServiceContext.CreatePartial(contentService: Mock.Of<IContentService>());