I'm interested in writing unit tests (using NUnit) for some service classes created using ServiceStack, using the "New API" (inheriting from ServiceStack.ServiceInterface.Service). The services' Db property is properly auto-wired when hosted in an ASP.NET application using AppHost, but I can't seem to figure out the proper technique when running outside of that environment. I see a variety of testing-related namespaces and classes in ServiceStack but can't find a clear example where a service's Db property is getting injected, as opposed to simply setting up a connection factory directly and then calling the various IDbConnection extension methods (Insert, Select, etc.).
I have tried having my test class inherit from ServiceStack.ServiceInterface.Testing.TestBase and overriding its Configure method to register an IDbConnectionFactory (using ":memory:"), as well as setting OrmLiteConfig.DialectProvider = SqliteDialect.Provider;
in my TestFixtureSetUp, but I continue to get a NullReferenceException when calling my service methods (at at ServiceStack.ServiceInterface.Service.get_Db()). It seems that the Funq container is not auto-wiring anything.
SQLite itself is properly set up, which I'm able to confirm with simpler unit tests that bypass my service classes and simply do direct IDbConnection calls.
What am I missing?
Edit
It appears that unit-testing ServiceStack services requires the existence of a host and a client, although it looks like there are ways to set this up to avoid the serialization cost (using the DirectServiceClient, as shown here) -- though I haven't succeeded in getting that to work in my case. I managed to get this working using an AppHostHttpListenerBase approach (see here) although it's more of an integration test than a unit one (and is accordingly slower).
The docs on Testing shows a couple of different approaches for injecting dependencies.
If you look at the implementation for the base Service it just creates the Db from the IDbConnectionFactory
:
private IDbConnection db;
public virtual IDbConnection Db
{
get { return db ?? (db = TryResolve<IDbConnectionFactory>().OpenDbConnection()); }
}
That it just resolves from the local or Global IResolver
IOC container:
public static IResolver GlobalResolver { get; set; }
private IResolver resolver;
public virtual IResolver GetResolver()
{
return resolver ?? GlobalResolver;
}
public virtual T TryResolve<T>()
{
return this.GetResolver() == null
? default(T)
: this.GetResolver().TryResolve<T>();
}
So to inject your own dependencies (when using Service base class) you just need to configure a IAppHost
with your dependencies your services need which you can do with:
using (var appHost = new BasicAppHost {
ConfigureContainer = c => {
c.Register<IDbConnectionFactory>(new ...);
}
}.Init())
{
//...
}
Which you can then set on your service along with any of your own dependencies your service needs, e.g:
var service = appHost.ResolveService<MyService>();
Which will autowire all dependencies configured in your AppHost, you can also add your own adhoc test-specific dependencies via normal property access, e.g:
var service.MyDependency = new Mock<IMyDependency>().Object;
From then on you can just call and test your C# class methods as per usual:
var response = service.Get(new RequestDto { ... });
Assert.That(response.Result, Is.Equal("Expected Result from DB"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With