Unit test ServiceStack services in ServiceStack 3.9.71 - c#

I recently took a .Net project over which exposes DAOs from a Microsoft SQL Database via ServiceStack(3.9.71) REST API. Since I am gonna refactor some parts I want to unit test (at least) all servicestack services. For a better understanding I quickly draft how the implementation works.
Each Service contains a property of type DBService which encapsulates all database accesses of all services. Unfortunately this is a concrete class which makes it hard to mock. The DI.Container wrappes ServiceStack's IOC.
public class SomeService : Service
{
public DBService { get { return DI.Container.Resolve<DBService>(); } }
public object Get(SomeDataClass class)
{
var response = DBService.SomeServiceGet();
return response;
}
// other code omitted
}
The DBService looks like this (draft):
public class DBService
{
public IDbConnectionFactory DBFactory { get { return DI.Container.Resolve<IDbConnectionFactory>(); } }
public SomeServiceResponse SomeServiceGet()
{
//DB Access here...
// ...
}
public SomeOtherServiceResponse SomeOtherServiceGet()
{
//...
}
// following about 30 other methods for all the services (POST,GET,PUT etc)
}
I read the detailed response to this question but I was not able to create and initialize a BasicAppHost in ServiceStack 3.9.71 since it immediately threw a System.TypeLoadExceptionMethod 'get_VirtualPathProvider'.
On the other hand I was thinking that I do not actually need a BasicAppHost. I just have to unit test the DBService and then the servicestack services with a somehow mocked DBService. The only problem I have is that DBService is not an interface and that I am actually not sure how to deal (mock) with the SQL database and the IOC.
[UPDATE]
Unfortunately I am still not able to test a service since I can not just new the service in my test. If I do so I get:
System.TypeLoadExceptionCould not load type 'ServiceStack.ServiceHost.IService' from assembly
Here is my test:
[Fact]
public void SomeDataTest()
{
var serviceUnderTest = new SomeService();
var response = serviceUnderTest.Get(new SomeDataClass());
Assert.NotNull(response);
}
I guess the problem is that the services strongly uses alot of properties which are injected via the IOC. How can I mock that? Creating a BasicAppHost and retrieving the service from there also does not work which I already mentioned.

If you are just testing your service class, then you can directly mock any dependencies:
[Fact]
public void SomeDataTest(
{
var serviceUnderTest = new SomeService();
var logger = new Mock<ILogger>(); // Rhino mocks fashion.
serviceUnderTest.Logger = logger.Object;
var response = serviceUnderTest.Get(new SomeDataClass());
Assert.NotNull(response);
}
There's an page in their older docs here about integration testing in case you want to test the AppHost
Edit: there's an example of mocking the service dependencies here.

Related

How to Mock an Autofac Aggregate Service with Moq?

I'm on .NET 4.6.2 and using the following versions of the assemblies via Nuget:
Service
Autofac - 4.8.1
Autofac.Extras.AggregateService - 4.1.0
Autofac.Wcf - 4.1.0
Castle.Core - 4.3.1
Tests
Autofac.Extras.Moq - 4.3.0
Moq - 4.10.1
The setup I'm using for the host container is exactly like the "Getting Started" example from the Docs and you end up with a proxy generated from DynamicProxy, and this works well by eliminating the constructor overloads.
When it comes to unit testing the services that use this type of injection I seem to be stumbling on how to mock it out properly.
I've spent a few hours trying various approaches and none of them have panned out. Here's basically what I have:
public interface IMyAggregateService
{
IFirstService FirstService { get; }
ISecondService SecondService { get; }
IThirdService ThirdService { get; }
IFourthService FourthService { get; }
}
public class SomeController
{
private readonly IMyAggregateService _aggregateService;
public SomeController(IMyAggregateService aggregateService)
{
_aggregateService = aggregateService;
}
}
using (var mock = AutoMock.GetLoose())
{
//var depends = mock.Mock<IMyAggregateService>().SetupAllProperties(); //Not working
//depends.SetupProperty(p => p.IFirstService, ?? );
//depends.SetupProperty(p => p.ISecondService, ?? );
//depends.SetupProperty(p => p.IThirdService, ?? );
//depends.SetupProperty(p => p.IFourthService, ?? );
var sut = mock.Create<SomeController>();
Action action = () => sut.SomeAction();
action.Should().xxxx
}
So the first problem I had was that there are no setters on the IMyAggregateService so the SetupProperty method won't work. When I used SetupAllProperties, everything was null at run-time, so that won't work. I even pulled down the Autofac.Extras.AggregateService code and was checking out the Test project, but there's really nothing I can gleam from it that might help, except the AggregateServiceGenerator might be useful at some point.
So my questions is,
"How do I properly mock an aggregate service, and provide behaviors for it during unit testing?"
For extra credit I'd like to know also how to provide a specific implementation of any of the dependencies that are properties, like this:
using (var mock = AutoMock.GetLoose())
{
mock.Provide<IFirstService>(this.MyImplProperty);
"How do I properly mock an aggregate service, and provide behaviors
for it during unit testing?"
Try to do smth like this (it is not using automoq just a moq :))
var firstServiceImpl= new Mock<IFirstService>();
var secondServiceImp2= new Mock<ISecondService>();
var myAggregateServie= new Mock<IMyAggregateService>();
myAggregateServie.SetupGet(x => x.FirstService ).Returns(firstServiceImpl);
myAggregateServie.SetupGet(x => x.SecondService ).Returns(secondServiceImp2);
.
.
.
And then you can mock behaviours of your services, and verify calls, some pseudo code will look like this.
//Mock as above
//Mock service behavior
firstServiceImpl.Setup(m=>m.Method1()).Returns(1)
//test method of you controller, lets assume that the method1 of controller
//is only calling firstService method named Method1()
var result = SampleController.Method1();
Assert.IsTrue( result == 1)
firstService.Verify(m=>m.Method1(), Times.Once()).

How to mock a class that is constantly changing?

I have a class XrmServiceContext and it changes each time the CRM configuration changes.
My service class accepts it in its constructor:
public class fooService(XrmServiceContext xrmServiceContext)
{
//implementation
}
I need to mock XrmServiceContext in order to set up expectations and verify behavior for my unit tests.
How do I mock this class in order to define behavior in my tests for fooService?
I would do this by creating a fake IOrganizationService object used in the constructor for XrmServiceContext, I recommend using: https://github.com/jordimontana82/fake-xrm-easy. You can learn more about how to use FakeXrmEasy, personally I found it very easy, by looking at https://dynamicsvalue.com/get-started/overview.
Here is brief overview of using the library for your purpose:
var context = new XrmFakedContext();
context.ProxyTypesAssembly = Assembly.GetAssembly(typeof(Account));
//You'll need to setup this fake to have the data necessary to support your use cases for XrmServiceContext.
var account = new Account() { Id = Guid.NewGuid(), Name = "My First Faked Account yeah!" };
context.Initialize(new List<Entity>() {
account
});
var service = context.GetFakedOrganizationService();
using (var context = new XrmServiceContext(service))
{
//Create instance of fooService class
var testableFooService = new fooService(context);
//TODO: Run your test.
}
XrmServiceContext should be considered a 3rd party API.
Create an abstraction of the functionality you want from the service and wrap/adapt the context in the implementation.
public interface IXrmServiceContext {
//api endpoints you want
}
So instead of passing around the concrete service context pass the abstractions to your services.
public class fooService {
public fooService (IXrmServiceContext xrmServiceContext){
}
//implementation
}
This will make it a lot easier to set up expectations and verify behavior for your unit tests.

Unit Testing a controller that uses windows authentication

-------Please see updates below as I now have this set up for dependency injection and the use of the MOQ mocking framework. I'd still like to split up my repository so it doesn't directly depend on pulling the windowsUser within the same function.
I have a Web API in an intranet site that populates a dropdown. The query behind the dropdown takes the windows username as a parameter to return the list.
I realize I don't have all of this set up correctly because I'm not able to unit test it. I need to know how this "should" be set up to allow unit testing and then what the unit tests should look like.
Additional info: this is an ASP.NET MVC 5 application.
INTERFACE
public interface ITestRepository
{
HttpResponseMessage DropDownList();
}
REPOSITORY
public class ExampleRepository : IExampleRepository
{
//Accessing the data through Entity Framework
private MyDatabaseEntities db = new MyDatabaseEntities();
public HttpResponseMessage DropDownList()
{
//Get the current windows user
string windowsUser = HttpContext.Current.User.Identity.Name;
//Pass the parameter to a procedure running a select query
var sourceQuery = (from p in db.spDropDownList(windowsUser)
select p).ToList();
string result = JsonConvert.SerializeObject(sourceQuery);
var response = new HttpResponseMessage();
response.Content = new StringContent(result, System.Text.Encoding.Unicode, "application/json");
return response;
}
}
CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
public ExampleController()
{
_exampleRepository = new ExampleRepository();
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 1
I have updated my Controller based on BartoszKP's suggestion to show dependency injection.
UPDATED CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
//Dependency Injection
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 2
I have decided to use MOQ as a mocking framework for unit testing. I'm able to test something simple, like the following. This would test a simple method that doesn't take any parameters and doesn't include the windowsUser part.
[TestMethod]
public void ExampleOfAnotherTest()
{
//Arrange
var mockRepository = new Mock<IExampleRepository>();
mockRepository
.Setup(x => x.DropDownList())
.Returns(new HttpResponseMessage(HttpStatusCode.OK));
ExampleController controller = new ExampleController(mockRepository.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
//Act
var response = controller.DropDownList();
//Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
I need help testing the DropDownList method (one that does include code to get the windowsUser). I need advice on how to break this method apart. I know both parts shouldn't been in the same method. I don't know how to arrange splitting out the windowsUser variable. I realize this really should be brought in as a parameter, but I can't figure out how.
You usually do not unit-test repositories (integration tests verify if they really persist the data in the database correctly) - see for example this article on MSDN:
Typically, it is difficult to unit test the repositories themselves, so it is often better to write integration tests for them.
So, let's focus on testing only the controller.
Change the controller to take IExampleRepository in its constructor as a parameter:
private IExampleRepository _exampleRepository;
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
Then, in your unit tests, use one of mocking frameworks (such as RhinoMock for example) to create a stub for the sole purpose of testing the controller.
[TestFixture]
public class ExampleTestFixture
{
private IExampleRepository CreateRepositoryStub(fake data)
{
var exampleRepositoryStub = ...; // create the stub with a mocking framework
// make the stub return given fake data
return exampleRepositoryStub;
}
[Test]
public void GivenX_WhenDropDownListIsRequested_ReturnsY()
{
// Arrange
var exampleRepositoryStub = CreateRepositoryStub(X);
var exampleController = new ExampleController(exampleRepositoryStub);
// Act
var result = exampleController.DropDownList();
// Assert
Assert.That(result, Is.Equal(Y));
}
}
This is just a quick&dirty example - CreateRepositoryStub method should be of course extracted to some test utility class. Perhaps it should return a fluent interface to make the test's Arrange section more readable on what is given. Something more like:
// Arrange
var exampleController
= GivenAController()
.WithFakeData(X);
(with better names that reflect your business logic of course).
In case of ASP.NET MVC, the framework needs to know how to construct the controller. Fortunately, ASP.NET supports the Dependency Injection paradigm and a parameterless constructor is not required when using MVC unity.
Also, note the comment by Richard Szalay:
You shouldn't use HttpContext.Current in WebApi - you can use base.User which comes from HttpRequestBase.User and is mockable. If you really want to continue using HttpContext.Current, take a look at Mock HttpContext.Current in Test Init Method
One trick that I find very useful when trying to make old code testable when said code is accessing some global static or other messy stuff that I can't easily just parameterize is to wrap access to the resource in a virtual method call. Then you can subclass your system under test and use that in the unit test instead.
Example, using a hard dependency in the System.Random class
public class Untestable
{
public int CalculateSomethingRandom()
{
return new Random().Next() + new Random().Next();
}
}
Now we replace var rng = new Random();
public class Untestable
{
public int CalculateSomethingRandom()
{
return GetRandomNumber() + GetRandomNumber();
}
protected virtual int GetRandomNumber()
{
return new Random().Next();
}
}
Now we can create a testable version of the class:
public class Testable : Untestable
{
protected override int GetRandomNumber()
{
// You can return whatever you want for your test here,
// it depends on what type of behaviour you are faking.
// You can easily inject values here via a constructor or
// some public field in the subclass. You can also add
// counters for times method was called, save the args etc.
return 4;
}
}
The drawback with this method is that you can't use (most) isolation frameworks to implement protected methods (easily), and for good reason, since protected methods are sort of internal and shouldn't be all that important to your unit tests. It's still a really handy way of getting things covered with tests so you can refactor them, instead of having to spend 10 hours without tests, trying to do major architectual changes to your code before you get to "safety".
Just another tool to keep in mind, I find it comes in handy from time to time!
EDIT: More concretely, in your case you might want to create a protected virtual string GetLoggedInUserName(). This will technically speaking keep the actual call to HttpContext.Current.User.Identity.Name untested, but you will have isolated it to the simplest smallest possible method, so you can test that the code is calling the correct method the right amount of times with the correct args, and then you simply have to know that HttpContext.Current.User.Identity.Name contains what you want. This can later be refactored into some sort of user manager or logged in user provider, you'll see what suits best as you go along.

How to mock web service call with Moq?

The using below hits an external resource that I do not want to actually hit. I want to test someResult and the code that uses it, but every time I run my unit test, this code still tries to hit the real web service. How do I use moq to fake the real call to the web service, but not mock the rest of the code within the using?
public IMyInterface.SomeMethod()
{
// hits a web service
using ( mySoapClient client = new mySoapClient() )
{
var someResult = client.DoSomething();
...
...
}
}
[TestMethod()]
public void SomeMethodTest()
{
IMyInterface target = new MyInterface();
target.SomeMethod();
// Assert....
}
You need to decouple the web service implementation from the consumer
public class ClassIWantToTest
{
public ClassIWantToTest(IServiceIWantToCall service) {}
public void SomeMethod()
{
var results = service.DoSomething();
//Rest of the logic here
}
}
Now you can use Moq to mock the IServiceIWantToCall in order to test the logic of SomeMethod
To add to pickles' answer, I created an interface for my current service calls named IService. I then created a ServiceMock class that inherits the interface and added a global variable named _service. In the constructor I instantiate the mock service and set up all the methods of the interface as such:
public class ServiceMock : IService
{
Mock<IService> _serviceMock;
public ServiceMock()
{
_serviceMock = new Mock<IService>();
_serviceMock.Setup(x => x.GetString()).Returns("Default String");
SomeClass someClass = new SomeClass();
someClass.Property1= "Default";
someClass.Property2= Guid.NewGuid().ToString();
_serviceMock.Setup(x => x.GetSomeClass()).Returns(someClass);
}
public string GetString()
{
return _serviceMock.Object.GetString();
}
public License GetSomeClass()
{
return _serviceMock.Object.GetSomeClass();
}
}
You then inject this class into your code instead of the actual web service. It will return the values you set it up to return. You can now test without depending on your web service.
You first have to be able to inject the web service. Creating a new one inside SomeMethod() "tightly couples" the method to the production code; you can't dynamically tell it to create something other than a mySoapClient.
Since you want to create and destroy them, might I suggest that the code you want to test accept a Func<IMySoapClient> as a method parameter or as a constructor parameter. It would look something like this:
public IMyInterface.SomeMethod(Func<IMySoapClient> clientFactory)
{
// hits a web service
using ( mySoapClient client = clientFactory() )
{
var someResult = client.DoSomething();
...
...
}
}
... or:
public class MyClass:IMyInterface
{
private Func<IMySoapClient> MySoapClientFactoryMethod;
public MyClass(Func<IMySoapClient> clientFactoryMethod)
{
MySoapClientFactoryMethod = clientFactoryMethod;
}
...
public IMyInterface.SomeMethod()
{
// hits a web service
using ( mySoapClient client = MySoapClientFactoryMethod() )
{
var someResult = client.DoSomething();
...
...
}
}
}
Now, when you create the object you are trying to test, you define a function that generates the appropriate Moq mock of the Soap service, which has the behavior you would expect from the real client without the side effects (including being able to tell that the code Dispose()d of the client), and pass that function into the class or method that you're testing. In production, you could simply define the function as ()=>new mySoapClient(), or you could set up an IoC framework and register mySoapClient as an IMySoapClient, then also register MyClass; most IoC frameworks are smart enough to see the delegate as a parameter and generate the method that injects the registered dependency.

NoSQL - How to mock database for unit testing?

I'm researching NoSQL databases and have a question regarding unit testing. What is the appropriate method to unit test the business logic? How does one mock a NoSQL database?
Your business logic should not touch the database directly, but rather go through a database access layer. This lets you mock that intermediate layer for unit testing. To do this, you can use dependency injection and mocking. There are frameworks that can help you with both of these things, but you can also do it by hand. Here's an example:
Say we have a DAL:
public class DBDataProvider: IDataProvider
{
public string getData()
{
//SQL to get data from actual database.
}
}
As you can see, this implements an interface for something that provides data for your business layer. It might look something like this:
public Interface IDataProvider
{
String getData();
}
Your business layer might look something like this:
public BusinessClass
{
private IDataProvider dataProvider;
public BusinessClass()
{
dataProvider = new DBDataProvider();
}
public BusinessClass(IDataProvider provider)
{
dataProvider = provider;
}
public void doBusinessStuff()
{
dataProvider.getData();
//Do something with data.
}
}
So now in your production code, you will make your business class using the default constructor, which will automatically make your class with a connection to the DB. However, notice that we can create a BusinessClass with an IDataProvider that we specify. So, you can make a "fake" data provider just for testing:
public class MockDataProvider: IDataProvider
{
public string getData()
{
//return some expected result that you can control, without doing a DB call.
}
}
Now in your test, you can create a new MockDataProvider, and pass that into the constructor for BusinessClass. Your business class will now use your mock data provider, instead of the real DB.
Here I did everything by hand, but it gives you an idea of how this works. In real life, you can use mocking and dependency injection frameworks to write a bunch of that code for you.
The same way you mock any dependency. Write a nice, neat contract from which implementation details can be abstracted away, then mock that contract. Typically this is done by using the Data Access Layer as the contract(s).
Without getting into real implementation details, lets say you have a query in your method you want to test: (note, i copied this code from a ravenDB example, but i know 0 about ravenDB, so it might not even compile)
public void SomeMethod()
{
var name = "Hello";
var motto = "World";
using (var docStore = new DocumentStore("localhost", 8080).Initialize())
using (var session = documentStore.OpenSession()){
session.Store(new Company { Name = name, Motto = motto });;
session.SaveChanges();
}
}
That's going to be pretty hard to mock / test because it requires a db on localhost on 8080. Now, if you separate this logic out into another class:
public class AwesomeDAL
public virtual void AddCompany(string name, string motto){
using (var docStore = new DocumentStore("localhost", 8080).Initialize())
using (var session = documentStore.OpenSession()){
session.Store(new Company { Name = name, Motto = motto });;
session.SaveChanges();
}
}
and allow for the injection of the dependency (AwesomeDal):
public class ClassBeingTested
{
public AwesomeDal DAL { get; set; }
public ClassBeingTested() : this(new AwesomeDal()){}
public ClassBeingTested(AwesomeDal dal)
{
this.DAL = dal;
}
public void SomeMethod()
{
var name = "Hello";
var motto = "World";
this.DAL.AddCompany(name, motto);
}
}
And you can now test the BL code in isolation. Or you can simulate database exceptions, or anything else you need to test because your data access layer is abstracted, and its implementation is easily mockable with a framework like Moq or RhinoMocks
In addition to the already posted (correct) answers, let me propose an alternative solution: Use a real development database! Nothing is a more realistic mock that the real thing. If you test on it directly, at least you know that your code will actually run.
If you can abstract away your database easily, I recommend doing that, though.

Categories