1

We're using ServiceStack for a client project with several distinct problem domains, which we'd prefer to keep separated. We've developed a testing framework that spins up an AppHostHttpListener and sets up an in-memory test database using SQLite and DbUp - but, as you know, a test session's AppDomain can only have one AppHost at a time.

On the other hand, we have two different AppHosts that we want to deploy, let's call them Foo and Bar. Foo accepts requests and passes them to Bar, so Foo -> Bar, and Bar is standalone.

We want to be able to write end-to-end integration tests that exercise instances of both Foo and Bar. With ServiceStack's limitation of one AppHost per AppDomain, we seem to have the following options:

  1. Spin up a new AppDomain for each AppHost inside the test session and control their lifetime across a MarshallByRef boundary. Not sure how this would perform sharing 'test connections' between AppHosts though.
  2. Mock out the external service. This is the textbook answer, but these systems are critical enough that we'd like to see when changes to one service break the other.
  3. Make the endpoints pluggable so that they can be loaded in the same AppHost for testing, but under different sub-URLs. The way I see it, this would require the endpoints to share AuthFeature, IDbConnectionFactory etc, so we would lose that flexibility.

My questions to you are:

  1. Which option would you go with?
  2. Can you recommend another approach that would enable us to test integration of multiple ServiceStack endpoints in memory?
Community
  • 1
  • 1
Sebastian Nemeth
  • 5,505
  • 4
  • 26
  • 36

1 Answers1

1

The only way to test multiple Services in memory is to combine them in the same Test AppHost which will only need the to register the dependencies the integration tests are testing. In memory Integration tests normally have a Custom AppHost built to task, the AppHost isn't part of the test.

The alternative is to use IIS Express and start instances of the endpoints used in the integration test before running them.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • Hi mythz! I've seen you (or some other ServiceStack freaks) post about spinning up multiple AppHosts in different AppDomains before, is there a reason why you don't bring it up now? I'm actually playing around with the idea myself to gauge it's feasability with Xunit and so far it seems promising... – Sebastian Nemeth Apr 21 '16 at 17:28
  • @Martaver it's an option, but it's not something I'd recommend as it's more difficult to setup than a single Test AppHost and it's neither a "full integration test" which hosting the actual instance on IIS Express would be more representative of - so I'm not seeing the benefit of doing more work for a boutique integration test setup that isn't representative of hosting on production. – mythz Apr 21 '16 at 17:46
  • Similar thoughts had crossed our minds about the distance from a production environment... It's open to debate, of course, but what really would you say is left out by doing integration testing in memory as compared to using an IIS instance? – Sebastian Nemeth Apr 21 '16 at 18:05
  • @Martaver Most of our Integration Tests are in-memory self-hosting integration tests that each have a custom AppHost configured to only register what dependencies it needs for the integration test. That's our preference, it's small, focused, isolated and in-memory with great debugging support. – mythz Apr 21 '16 at 18:11
  • Okay that makes sense, and then you configure whatever mocked dependencies you may need on the 'test host' container? You must be firing up a different app host for each test scenario, then - how does that go with speed? Our AppHostHttpListenerBase takes around 2.5 seconds to spin up. – Sebastian Nemeth Apr 21 '16 at 18:13
  • @Martaver performance hasn't been a concern, we only have 1 custom AppHost per test fixture where all tests run against the same custom AppHost instance. 2.5s sounds pretty slow though, there's an initial wait for R# test runner to build the project but then jumping to each test fixture is sub 1s. – mythz Apr 21 '16 at 19:09
  • Are you starting up a full HTTP listener though? We tried to use an appHost without HTTP, just resolving requests to service calls in-proc using Host.ExecuteService and a MockHttpRequest, but parts of the request pipeline, like validation, seemed to be left out. Thanks for answering all these questions, by the way :) – Sebastian Nemeth Apr 21 '16 at 19:15
  • @Martaver yes we're using a self-hosted http listener host, you can find some examples from [ServiceStack.WebHost.Endpoints.Tests](https://github.com/ServiceStack/ServiceStack/tree/master/tests/ServiceStack.WebHost.Endpoints.Tests). I'm running on a decent (2.5yro) MBP w/ SSD which might help. But I'm not running all the tests locally, just the ones I'm working on and just let TeamCity run the entire test suite. Not sure how many services you have but if you have 100+, maybe consider splitting them in different .dlls and only register the Assemblies you need - or nag boss for better hardware:) – mythz Apr 21 '16 at 19:30
  • Hah! I wish I had one to nag! Thanks for the reality check, this helped immensely. – Sebastian Nemeth Apr 21 '16 at 19:34