Most services are, as you say, provided as interfaces so it's mostly down to mocking them for your purposes.
Having said that, some things are harder to mock than they first appear. Here's what I use to mock CommercePipelineExecutionContext
:
static class FakeCommercePipelineExecutionContext
{
public static CommercePipelineExecutionContext CreateContext()
{
return new CommercePipelineExecutionContext(CreateOptions(), CreateLogger());
}
private static ILogger CreateLogger()
{
return new NullLogger();
}
private static IPipelineExecutionContextOptions CreateOptions()
{
return new CommercePipelineExecutionContextOptions(CreateCommerceContext());
}
private static CommerceContext CreateCommerceContext()
{
var context = new CommerceContext(new NullLogger(), null);
context.Environment = new CommerceEnvironment();
return context;
}
}
class NullLogger : ILogger
{
public IDisposable BeginScope<TState>(TState state)
{
return new NullDisposable();
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
}
}
class NullDisposable : IDisposable
{
public void Dispose()
{
}
}
That's enough to make access to policies, models, and objects work as expected. I have tests using that infrastructure that assert that the pipeline was aborted.
Some pipelines like IFindEntityPipeline
and IPersistEntityPipeline
can also be tricky to mock, so it might be worth creating helpers for them.