5

What are common or effective approaches for making Pipelines in Sitecore unit testable? I recently updated some code to use custom pipelines and then found I could no longer unit test it :-(

In the past, I have set up unit test projects which load up all the config files and actually connect to Sitecore, but I don't think this is really best-practice, so want to avoid this if possible.

I am currently using FakeDb along with xunit and a load of other test-related libraries such a Moq, NSubstitute etc. I'm aware I could unit test individual pipeline steps, but could not test the method in question without invoking the whole pipeline.

2
  • Would have added this as a comment but don't have the rep :( I would say what you are trying to do here is integration testing, so I don't think its that bad to have Sitecore back the test, but happy to be wrong. Saving unit testing for building and validating the individual pipeline steps is how I would approach this. I don't see it as my responsibility to test if Sitecore is doing its job, so generally, I try and keep Sitecore out of my business logic creating focused interfaces that cross system boundaries, and then I can mock these when unit testing.
    – Gravypower
    May 21, 2018 at 10:19
  • People start with unit testing and then move to the approach you mentioned (Test has configs and loads Sitecore). But I am surprised to see you move in the opposite direction. This approach you did is the proper integration testing. You said it is not a best practice because perhaps you don't see it used anywhere. Even I am surprised by the dev fantasy towards unit testing and code coverage. Both are too old and do not provide as good value as integration tests.Taken from linkedin.com/pulse/… Sep 17, 2018 at 5:25

1 Answer 1

4

Had a bit of a think about how to do this:

Test the processor steps

So the first thing to do is make sure all your code logic is off loaded to a service or manager class. The processor class really should just be responsible for creating the service/manager class (by constructor injection of course :) ) and then calling the appropriate method.

So the main set of unit testing can be done for the individual functionality of the pipeline.

Test the processor

With the container now being a part of Sitecore in 8.2+, you can now test some processors directly. Pipelines now support the resolve="true" attribute that will use the container to create the processor and inject any dependencies. So those are now testable. For processors that do not inject dependencies, you are back to FakeDb and mocking everything.

Test the pipeline

To test the pipeline as a whole and not have all the Sitecore binaries, config etc... (I agree, this isn't a great practice), we are going to have to write our own version of CorePipeline.Run as a kind of test harness. That would then take the args and push them through the Process Method of each processor.

Initially - this sounds like it would be fairly simple to do, at a very basic level you could even do something as simple as:

public void TestMyPipeline()
{
    var args = new Mock<ProcessorArgs>();

    // TODO: populate the properites on the args mock

    var processor1 = new Processor1(dependency1Mock.Object, dependency2Mock.Object);
    processor1.Process(this, args);

    var processor2 = new Processor1(dependency1Mock.Object, dependency2Mock.Object);
    processor2.Process(this, args);

    // etc...

    // Add your test assersions
}

But... ultimately, you still have the same problem. You need to mock or create any dependencies that get used in those processors and there is a lot to setup.

What is the best option?

For me - generally, unit testing each processor individually normally covers 99% of what is going to require testing. The extra overhead of running the entire pipeline gets into the rule of diminishing returns.

But you would have to evaluate how far you wanted to take the testing for your project.

3
  • 2
    I'm aware I could unit test individual pipeline steps, but could not test the method in question without invoking the whole pipeline. The issue is testing an entire pipeline process, not individual processes.
    – jammykam
    Nov 8, 2017 at 14:26
  • 1
    Updated the answer to cover that now.
    – Richard Seal
    Nov 8, 2017 at 17:34
  • 1
    Thanks for the comprehensive answer @RichardSeal (and for the comment @jammykam). Nov 9, 2017 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.