Skip to content
Demis Bellot edited this page Feb 24, 2014 · 15 revisions

The tests in ServiceStack.WebHost.Endpoints.Tests show good examples of how to create stand-alone integration tests that just use a self-hosted HttpListener AppHost.

Example Stand-alone Integration tests

Unit testing

If you want to unit test a ServiceStack Service in isolation there are a couple of different approaches you can take. The base Service class itself is just a simple C# class which lets you define and inject dependencies manually or by using the built-in IOC container.

We'll illustrate both approaches using this simple unit test example that tests this simple Service:

// DTOs
public class FindRockstars
{
   public int? Aged { get; set; }
   public bool? Alive { get; set; }
}

public class GetStatus
{
   public string LastName { get; set; }
}

public class RockstarStatus
{
   public int Age { get; set; }
   public bool Alive { get; set; }
}

public class Rockstar
{
   [AutoIncrement]
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int? Age { get; set; }
}

// Implementation
public class SimpleService : Service
{
   public IRockstarRepository RockstarRepository { get; set; }

   public List<Rockstar> Get(FindRockstars request)
   {
      return request.Aged.HasValue
          ? Db.Select<Rockstar>(q => q.Age == request.Aged.Value)
          : Db.Select<Rockstar>();
   }

   public RockstarStatus Get(GetStatus request)
   {
      var rockstar = RockstarRepository.GetByLastName(request.LastName);
      if (rockstar == null)
          throw HttpError.NotFound("'{0}' is not a Rockstar".Fmt(request.LastName));

      var status = new RockstarStatus
      {
          Alive = RockstarRepository.IsAlive(request.LastName)
      }.PopulateWith(rockstar); //Populates with matching fields

      return status;
   }
}

This Service provides 2 operations, FindRockstars which makes db queries directly in the service class itself, and GetStatus which uses a repository instead for all its Data access.

Using an in-memory database

If you're accessing Db from directly within your service implementation you're going to want to make use of a real DB given the ADO.NET IDbConnection requires a lot of effort to mock. You can do this in the same way you would register your dependencies in ServiceStack itself, by using the built-in IOC. For a unit test we can do this without an AppHost by just use a new Container in your TestFixtureSetup, e.g:

Test Setup

private ServiceStackHost appHost;

[TestFixtureSetUp]
public void TestFixtureSetUp()
{
    appHost = new BasicAppHost().Init();
    var container = appHost.Container;

    container.Register<IDbConnectionFactory>(
        new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));

    container.RegisterAutoWiredAs<RockstarRepository, IRockstarRepository>();

    container.RegisterAutoWired<SimpleService>();

    using (var db = container.Resolve<IDbConnectionFactory>().Open())
    {
        db.DropAndCreateTable<Rockstar>();
        db.InsertAll(SeedData);
    }
}

[TestFixtureTearDown]
public void TestFixtureTearDown()
{
    appHost.Dispose();
}

With everything setup we can now test the service just like a normal C# class in isolation independently of ServiceStack itself:

[Test]
public void Using_in_memory_database()
{
    //Resolve the autowired service from IOC and set Resolver for the base class
    var service = appHost.Container.Resolve<SimpleService>(); 

    var rockstars = service.Get(new FindRockstars { Aged = 27 });

    rockstars.PrintDump(); //Print a dump of the results to Console

    Assert.That(rockstars.Count, Is.EqualTo(SeedData.Count(x => x.Age == 27)));

    var status = service.Get(new GetStatus { LastName = "Vedder" });
    Assert.That(status.Age, Is.EqualTo(48));
    Assert.That(status.Alive, Is.True);

    status = service.Get(new GetStatus { LastName = "Hendrix" });
    Assert.That(status.Age, Is.EqualTo(27));
    Assert.That(status.Alive, Is.False);

    Assert.Throws<HttpError>(() =>
        service.Get(new GetStatus { LastName = "Unknown" }));
}

Manually injecting dependencies

If you prefer your unit tests not to use an in-memory database, you can instead choose to mock your dependencies. In this example we'll use a stand-alone Mock, but you can reduce boilerplate by using mocking library like Moq instead.

public class RockstarRepositoryMock : IRockstarRepository
{
    public Rockstar GetByLastName(string lastName)
    {
        return lastName == "Vedder"
            ? new Rockstar(6, "Eddie", "Vedder", 48)
            : null;
    }

    public bool IsAlive(string lastName)
    {
        return lastName == "Grohl" || lastName == "Vedder";
    }
}

[Test]
public void Using_manual_dependency_injection()
{
    var service = new SimpleService
    {
        RockstarRepository = new RockstarRepositoryMock()
    };

    var status = service.Get(new GetStatus { LastName = "Vedder" });
    Assert.That(status.Age, Is.EqualTo(48));
    Assert.That(status.Alive, Is.True);

    Assert.Throws<HttpError>(() =>
        service.Get(new GetStatus { LastName = "Hendrix" }));
}

This example doesn't need a container as we're injecting all the dependencies manually.

Community Resources

Stack Overflow



  1. Getting Started
    1. Create your first webservice
    2. Your first webservice explained
    3. ServiceStack's new API Design
    4. Designing a REST-ful service with ServiceStack
    5. Example Projects Overview
  2. Reference
    1. Order of Operations
    2. The IoC container
    3. Metadata page
    4. Rest, SOAP & default endpoints
    5. SOAP support
    6. Routing
    7. Service return types
    8. Customize HTTP Responses
    9. Plugins
    10. Validation
    11. Error Handling
    12. Security
    13. Debugging
  3. Clients
    1. Overview
    2. C# client
    3. Silverlight client
    4. JavaScript client
    5. Dart Client
    6. MQ Clients
  4. Formats
    1. Overview
    2. JSON/JSV and XML
    3. ServiceStack's new HTML5 Report Format
    4. ServiceStack's new CSV Format
    5. MessagePack Format
    6. ProtoBuf Format
  5. View Engines 4. Razor & Markdown Razor
    1. Markdown Razor
  6. Hosts
    1. IIS
    2. Self-hosting
    3. Messaging
    4. Mono
  7. Security
    1. Authentication/authorization
    2. Sessions
    3. Restricting Services
  8. Advanced
    1. Configuration options
    2. Access HTTP specific features in services
    3. Logging
    4. Serialization/deserialization
    5. Request/response filters
    6. Filter attributes
    7. Concurrency Model
    8. Built-in caching options
    9. Built-in profiling
    10. Form Hijacking Prevention
    11. Auto-Mapping
    12. HTTP Utils
    13. Virtual File System
    14. Config API
    15. Physical Project Structure
    16. Modularizing Services
    17. MVC Integration
  9. Plugins 3. Request logger 4. Swagger API
  10. Tests
    1. Testing
    2. HowTo write unit/integration tests
  11. Other Languages
    1. FSharp
    2. VB.NET
  12. Use Cases
    1. Single Page Apps
    2. Azure
    3. Logging
    4. Bundling and Minification
    5. NHibernate
  13. Performance
    1. Real world performance
  14. How To
    1. Sending stream to ServiceStack
    2. Setting UserAgent in ServiceStack JsonServiceClient
    3. ServiceStack adding to allowed file extensions
    4. Default web service page how to
  15. Future
    1. Roadmap

Clone this wiki locally