Based on the discussion in the answer by @mythz, this is my solution:
Use case like OP: Test the "main" service, and mock the "sub service", and like OP I'd want to do that with Unit test (so BasicAppHost), because it's quicker, and I believe it is easier to mock services that way (side note: for AppHost based integration test, SS will scan assemblies for (real) Services, so how to mock? Unregister from "container" and replace w. mock?).
Anyway, for the unit test:
My "main" service is using another service, via the IServiceGateway (which is the officially recommended way):
public MainDtoResponse Get(MainDto request) {
// do some stuff
var subResponse = Gateway.Send(new SubDto { /* params */ });
// do some stuff with subResponse
}
In my test setup:
appHost = new BasicAppHost().Init();
var mockGateway = new Mock<IServiceGateway>(); // using Moq
mockGateway.Setup(x => x.Send<SubDtoResponse>(It.IsAny<SubDto>()))
.Returns(new SubDtoResponse { /* ... */ });
container.Register(mockGateway.Object);
So the IServiceGateway must be mocked, and then the Send method is the important one. What I was doing wrong was to mock the service, when I should have mocked the Gateway.
Then call the main service (under test) in the normal fashion for a Unit Test, like in the docs:
var s = appHost.Container.Resolve<MainService>(); // must be populated in DI manually earlier in code
s.Get(new MainDto { /* ... */ })
PS: The mockGateway.Setup can be used inside each test, not necessarily in the OneTimeSetUp.