Isolating Service Fabric ServiceContext for unit testing - c#

I have a method in my Service fabric Stateless service application which get the configuration stored in Settings.xml from ServiceContext
public static string GetConnectionString()
{
if (context == null)
return string.Empty;
// return context.CodePackageActivationContext.GetConfigurationPackageObject("Config").Settings.Sections["MySection"].Parameters["ConnectionString"].Value;
ICodePackageActivationContext activationContext = context.CodePackageActivationContext;
ConfigurationPackage configPackage = activationContext.GetConfigurationPackageObject("Config");
ConfigurationSettings configSettings = configPackage.Settings;
string connectionString = configSettings.Sections["ConnectionData"].Parameters["ConnectionString"].Value;
return connectionString;
}
In the above code I split the code into many lines for easier understanding, actually i use the commented code in my application.
I need to write unit test for this method.
I could mock ServiceContext and ICodeActivationContext
But i could not create objects for ConfigurationSettings and ConfigurationPackage since they have internal constructors.
How do I isolate these classes in my unit test. Or should i exclude the service context part from my unit test.

Now you can use a NuGet package named ServiceFabric.Mocks, which offers mocks for most Service Fabric classes.
For example, you can use MockStatelessServiceContextFactory.Default to get a StatelessServiceContext mock.

I would create an interface that returns parameters from service fabric (one of them is the connection string). Then a class that implements the interface the way you wrote in the question. And that interface can be mocked used in unittesting.
The result is - that you cannot test the method that actually read from service parameters, but at least you can test everyone who uses it without the need to mock ServiceContext and alike.

I had an almost identical issue with the System.Printing PrintSystemJobInfo class, it has a sealed constructor so it proved very difficult to mock. I assume you are creating an interface that closely resembles the class you wish to mock, then creating a wrapper for the actual class that implements the interface.
A solution to your problem is to pass the parent class as a parameter in the constructor of the child class (so the child class has access to the parent methods and can build the real implementation that you intend to wrap).
The following code demonstrates how I did it with PrintSystemJobInfo;
using System;
using System.Printing;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
var server = new LocalPrintServer();
IPrintQueue testablePrintQueue = new RealPrintQueue(server);
IPrintSystemJobInfo printSystemJobInfo = testablePrintQueue.AddJob();
var result = printSystemJobInfo.IsBlocked;
Console.WriteLine(result);
}
public interface IPrintSystemJobInfo
{
bool IsBlocked { get; }
}
public interface IPrintQueue
{
IPrintSystemJobInfo AddJob();
}
public class RealPrintQueue:IPrintQueue
{
private PrintQueue _queue;
public RealPrintQueue(LocalPrintServer server)
{
_queue = server.DefaultPrintQueue;
}
public IPrintSystemJobInfo AddJob()
{
return new RealPrintSystemJobInfo(_queue);
}
}
public class RealPrintSystemJobInfo: IPrintSystemJobInfo
{
private PrintSystemJobInfo job;
public RealPrintSystemJobInfo(PrintQueue queue)
{
job = queue.AddJob();
}
public bool IsBlocked
{
get { return job.IsBlocked; }
}
}
}
}
I have tried to keep this as simple as possible so I have only wrapped IsBlocked property, but you could extend it to what ever you liked (obviously).

Related

Do not share static properties in tests

I have to write tests for existing code with xUnit. Here is a simplified problem I faced with:
using Xunit;
namespace XUnitTestProject1
{
public class UnitTest1
{
[Fact]
public void Test1()
{
GlobalHanler.StaticProperty = "some value";
}
[Fact]
public void Test2()
{
Assert.Null(GlobalHanler.StaticProperty);
}
}
public static class GlobalHanler
{
public static string StaticProperty;
}
}
GlobalHandler owns another object, both are static
When I run 2 tests together, Test2 fails because it can see the value that was set in Test1.
However, when I run Test2 separately, it succeeds.
My goal is to make 2 tests pass when they run together. I need somehow to reset global static property for each test separately, but I can't change the implementation of GlobalHandler
Setting StaticProperty in each test method seems not an option, because it will affect other tests running in parallel
In order to have testable code, you should first put the logic in a class that can be created as many times as needed and then use that class across your code by passing the reference.
Your production code can always use a singleton, but having no direct references to the singleton makes it testable.
Singletons and testing do not cohabit very well due to the possible side effects and unclear dependencies.
You should avoid using static. Instead of this, create a simple class and register it in your DI container as a singleton. Then you can test it easily.
Simple example:
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main()
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IQueueUrlProvider, QueueUrlProvider>()
.BuildServiceProvider();
Console.WriteLine(serviceProvider.GetService<IQueueUrlProvider>().QueueUrl);
}
public interface IQueueUrlProvider
{
string QueueUrl { get; }
}
public class QueueUrlProvider : IQueueUrlProvider
{
private readonly Lazy<string> _getQueueUrlLazy;
public string QueueUrl => _getQueueUrlLazy.Value;
public QueueUrlProvider()
{
_getQueueUrlLazy = new Lazy<string>(GetQueueUrl);
}
private string GetQueueUrl()
{
// get url here
return "your queue url";
}
}
}
https://dotnetfiddle.net/JjRh4q

Swapping between versions of a webservice c#

I wish to maintain code that calls an existing webservice but make it so I can call a newer version of the same webservice (based on a config setting). I'll need to have different namespaces as the webservice is the same name. Does anyone have any best practice patters for accomplishing this?
Thanks,
Steven
The "Factory" pattern (and probably "Facade" pattern) are your friends here.
So, given you have two services that implement a common method or set of methods you can do this kind of thing to make a general service factory:
I'm assuming you have two services called ServiceOld and ServiceNew (they could have the same name and sit in different namespaces as is your case). And that these services share a common method public string GetName();.
First I create an interface that embodies these services:
public interface IService
{
string GetName();
}
Now, if you can modify the service code directly you could implement this interface directly on your services, or you could perhaps inherit down your services and implement this interface. I'm going to assume that your services are both not under your control and are sealed. So I would implement two wrapper (or facade) classes.
public class ServiceOldWrapper : IService
{
private ServiceOld _inner = new ServiceOld();
public string GetName()
{
return _inner.GetName();
}
}
public class ServiceNewWrapper : IService
{
private ServiceNew _inner = new ServiceNew();
public string GetName()
{
return _inner.GetName();
}
}
Now I can write the factory class.
public class ServiceFactory
{
public IService CreateService()
{
if (configValueThatYouNeedToRead == "Old")
{
return new ServiceOldWrapper();
}
else
{
return new ServiceNewWrapper();
}
}
}
Now calling this becomes simple:
var sf = new ServiceFactory();
var s = sf.CreateService();
var name = s.GetName();
You probably will need to handle cleaning up your services a little better than I have so your code will be a bit more complicated, but this should get you started.

Mocking using Moq in c#

I have the following code:
public interface IProductDataAccess
{
bool CreateProduct(Product newProduct);
}
Class ProductDataAccess implements that interface.
public class ProductBusiness
{
public bool CreateProduct(Product newProduct)
{
IProductDataAccess pda = new ProductDataAccess();
bool result = pda.CreateProduct(newProduct);
return result;
}
}
In this case, how to create unit test for CreateProduct method by mocking the IProductDataAccess interface? I thought of having an public instance of IProductDataAccess within ProductBusiness and initialize it using Mock<IProductDataAccess> object but it is not a good practice to expose the data access to the UI layer. Can any one help me?
Classic example which demonstrates that if you cannot unit test a particular component, REFACTOR it!
This is why I love what any mocking framework enforces you to do - write decoupled code.
In your example, the ProductBusiness class is tightly coupled with the ProductDataAccess class. You could decouple it using (like most of the answers suggest) dependency injection. By doing so, you would end up depending on the IProductDataAccess abstraction and not on any concrete implementation of it.
Another point to note, when you are writing tests/specifications for the business layer, you would typically want to test the "behavior" and not the "state". So, although you could have asserts that verify if "true" was returned, your tests should really test if the expected data access calls that were set using MOQ were actually executed using the .Verify API of MOQ.
Try adding behavior tests where you expect an exception to be thrown (using the ".Throws" API) by the data access layer and check if you need any special handling at the business layer.
Like Kevin suggests, the following implementation of ProductBusiness will work:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result=_productDataAccess.CreateProduct(newProduct);
return result;
}
}
and use any xunit testing framework to write the test as:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess.Setup(m => m.CreateProduct(It.IsAny<Product>())).Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
//behavior to be tested
You should inject IProductDataAccess interface as a dependency:
public class ProductBusiness
{
private IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result = _productDataAccess.CreateProduct(newProduct);
return result;
}
}
Then you can replace it with a mock in your tests:
var productDataAccess = new Mock<IProductDataAccess>();
var productBusiness = new ProductBusiness(productDataAccess.Object);
With the way that you have currently designed your ProductBusiness class there is no way of changing the IProductDataAccess implementation using a mock. A recommended pattern for this is dependency-injection where you take the dependencies of a type through the constructor. So your class becomes:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result = _productDataAccess.CreateProduct(newProduct);
return result;
}
}
Now you are in a position to test your class by using a mocking framework like moq. For example:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess
.Setup(m => m.CreateProduct(It.IsAny<Product>()))
.Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
// ... test behaviour here
Now you can change how the mock behaves in your setup step and make sure that your CreateProduct method is behaving correctly.
I would also look at a dependency injection framework like castle-windsor. A dependency injection framework can automatically resolve dependencies meaning creating a new type is much easier as you don't have to manually new everything up. Also it means that you can change which implementation is used in one place and it changes everywhere.
You shouldn't instantiate a concrete ProductDataAccess inside your CreateProduct method.
Instead, IProductDataAccess should be an injectable dependency. This can be done in one of two ways:
Property injection:
public class ProductBusiness
{
IProductDataAccess Pda {get; set;}
}
var productBusiness = new ProductBusiness();
productBusiness.Pda = new ProductDataAccess();
productBusiness.Pda = new MockProductDataAccess();
Or constructor injection:
public class ProductBusiness
{
private readonly IProductDataAccess _pda;
public ProductBusiness(IProductDataAccess pda)
{
_pda = pda;
}
}
var productBusiness = new ProductBusiness(new ProductDataAccess());
var productBusiness = new ProductBusiness(new MockProductDataAccess());
Constructor injection is usually the recommend approach.
Property injection is used for optional dependencies (e.g., instantiate a concrete NullLogger by default in the constructor, and use the property to optionally inject a working logger).

How to type cast interface to a concrete type

I am trying to mock the ManagementObjectSearcher class and have created a IManagementInfo interface, so how can i cast the interface to the ManagementObjectSearcher class?
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info = s as IManagementInfo;
this creates me a null info object
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info =IManagementInfo(s);
this gives me run time error (cannot typecast)
You cannot do that. Do you want to do it so that you can write unit tests? If you are trying to mock a class that you have no control of, then you have to wrap it in another class.
public class MyManagementObjectSearcherWrapper : IManagementInfo
{
public void TheMethodToMock()
{
var searcher = new ManagementObjectSearcher();
// The code you want to mock goes here
}
}
And you run your code like this:
public void YourCode(IManagementInfo info)
{
info.TheMethodToMock();
}
Then YourCode() will take either your wrapper or the mocked object. You create your mock using the IManagementInfo interface.
It looks as if you are trying to wrap a 3rd party/system object in order to aid unit testing.
Say that your starting point is
public class Dependency {
public string Foo() {
return "foo"; // machine, system, time, something else, dependent result
}
public string Bar() {
return "bar";
}
}
public class MySimpleClass {
public string MyFunc() {
return new Dependency().Foo();
}
}
[TestMethod]
public void TestSimple() {
var client = new MySimpleClass();
Assert.AreEqual("foo", client.MyFunc());
}
We are creating the Dependency inside the call because we are considering the creation cost to be less important than holding on to an instance of the Dependency. This will be dependent upon the situation. We could as easily have created a Dependency in the ctor and stored a copy which we invoked each time. Either way, we have no control over the output which makes unit testing messy.
We need to create a proxy for it.
1. Define an interface for the members that we need
Most likely, we do not need to use all of the members of the wrappee so only include in the interface those about which we care.
public interface IDependencyProxy {
string Foo();
}
2. Create a Proxy Class
We then create a proxy class wrapping the dependency and implementing interface. Again, we can create at start or on a call by call basis.
public class DependencyProxy : IDependencyProxy {
public string Foo() {
return new Dependency.Foo();
}
}
3. Define our client code in terms of the interface
We modify our client code slightly to use the IDependencyProxy interface instead of the Dependency. There are a few ways of doing this. I generally use an internal ctor which takes the dependency chained from a public ctor. (Use [InternalsVisibleTo] to allow the unit tests to see it)
public class MyRevisedClass {
private readonly IDependencyProxy dependency;
public MyRevisedClass()
: this( new DependencyProxy()) {}
internal MyRevisedClass(IDependencyProxy dependency) {
this.dependency = dependency;
}
public string MyFunc() {
return dependency.Foo();
}
}
This allows us a default behaviour for the production code (invokes the System object) and allows us to mock out the results for unit testing.
[TestMethod]
public void TestRevisedDefault() {
var client = new MyRevisedClass();
Assert.AreEqual("foo", client.MyFunc());
}
[TestMethod]
public void TestRevisedWithMockedDependency() {
var dep = new Mock<IDependencyProxy>();
dep.Setup(mk => mk.Foo()).Returns("bar");
var client = new MyRevisedClass(dep.Object);
Assert.AreEqual("bar", client.MyFunc());
}

Fake ASMX Web Service Call

I built a .NET ASMX web service connecting to an SQL Server database. There is a web service call GetAllQuestions().
var myService = new SATService();
var serviceQuestions = myService.GetAllQuestions();
I saved the result of GetAllQuestions to GetAllQuestions.xml in the local application folder
Is there any way to fake the web service call and use the local xml result?
I just want to take the contents of my entire sql table and have the array of objects with correlating property names automatically generated for me just like with LINQ to SQL web services.
Please keep in mind that I am building a standalone Monotouch iPhone application.
Use dependency injection.
//GetSATService returns the fake service during testing
var myService = GetSATService();
var serviceQuestions = myService.GetAllQuestions();
Or, preferably, in the constructor for the object set the SATService field (so the constructor requires the SATService to be set. If you do this, it will be easier to test.
Edit: Sorry, I'll elaborate here. What you have in your code above is a coupled dependency, where your code creates the object it is using. Dependency injection or the Inversion of Control(IOC) pattern, would have you uncouple that dependency. (Or simply, don't call "new" - let something else do that - something you can control outside the consumer.)
There are several ways to do this, and they are shown in the code below (comments explain):
class Program
{
static void Main(string[] args)
{
//ACTUAL usage
//Setting up the interface injection
IInjectableFactory.StaticInjectable = new ConcreteInjectable(1);
//Injecting via the constructor
EverythingsInjected injected =
new EverythingsInjected(new ConcreteInjectable(100));
//Injecting via the property
injected.PropertyInjected = new ConcreteInjectable(1000);
//using the injected items
injected.PrintInjectables();
Console.WriteLine();
//FOR TESTING (normally done in a unit testing framework)
IInjectableFactory.StaticInjectable = new TestInjectable();
EverythingsInjected testInjected =
new EverythingsInjected(new TestInjectable());
testInjected.PropertyInjected = new TestInjectable();
//this would be an assert of some kind
testInjected.PrintInjectables();
Console.Read();
}
//the inteface you want to represent the decoupled class
public interface IInjectable { void DoSomething(string myStr); }
//the "real" injectable
public class ConcreteInjectable : IInjectable
{
private int _myId;
public ConcreteInjectable(int myId) { _myId = myId; }
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", _myId, myStr);
}
}
//the place to get the IInjectable (not in consuming class)
public static class IInjectableFactory
{
public static IInjectable StaticInjectable { get; set; }
}
//the consuming class - with three types of injection used
public class EverythingsInjected
{
private IInjectable _interfaceInjected;
private IInjectable _constructorInjected;
private IInjectable _propertyInjected;
//property allows the setting of a different injectable
public IInjectable PropertyInjected
{
get { return _propertyInjected; }
set { _propertyInjected = value; }
}
//constructor requires the loosely coupled injectable
public EverythingsInjected(IInjectable constructorInjected)
{
//have to set the default with property injected
_propertyInjected = GetIInjectable();
//retain the constructor injected injectable
_constructorInjected = constructorInjected;
//using basic interface injection
_interfaceInjected = GetIInjectable();
}
//retrieves the loosely coupled injectable
private IInjectable GetIInjectable()
{
return IInjectableFactory.StaticInjectable;
}
//method that consumes the injectables
public void PrintInjectables()
{
_interfaceInjected.DoSomething("Interface Injected");
_constructorInjected.DoSomething("Constructor Injected");
_propertyInjected.DoSomething("PropertyInjected");
}
}
//the "fake" injectable
public class TestInjectable : IInjectable
{
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", -10000, myStr + " For TEST");
}
}
The above is a complete console program that you can run and play with to see how this works. I tried to keep it simple, but feel free to ask me any questions you have.
Second Edit:
From the comments, it became clear that this was an operational need, not a testing need, so in effect it was a cache. Here is some code that will work for the intended purpose. Again, the below code is a full working console program.
class Program
{
static void Main(string[] args)
{
ServiceFactory factory = new ServiceFactory(false);
//first call hits the webservice
GetServiceQuestions(factory);
//hists the cache next time
GetServiceQuestions(factory);
//can refresh on demand
factory.ResetCache = true;
GetServiceQuestions(factory);
Console.Read();
}
//where the call to the "service" happens
private static List<Question> GetServiceQuestions(ServiceFactory factory)
{
var myFirstService = factory.GetSATService();
var firstServiceQuestions = myFirstService.GetAllQuestions();
foreach (Question question in firstServiceQuestions)
{
Console.WriteLine(question.Text);
}
return firstServiceQuestions;
}
}
//this stands in place of your xml file
public static class DataStore
{
public static List<Question> Questions;
}
//a simple question
public struct Question
{
private string _text;
public string Text { get { return _text; } }
public Question(string text)
{
_text = text;
}
}
//the contract for the real and fake "service"
public interface ISATService
{
List<Question> GetAllQuestions();
}
//hits the webservice and refreshes the store
public class ServiceWrapper : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From WebService");
//this would be your webservice call
DataStore.Questions = new List<Question>()
{
new Question("How do you do?"),
new Question("How is the weather?")
};
//always return from your local datastore
return DataStore.Questions;
}
}
//accesses the data store for the questions
public class FakeService : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From Fake Service (cache):");
return DataStore.Questions;
}
}
//The object that decides on using the cache or not
public class ServiceFactory
{
public bool ResetCache{ get; set;}
public ServiceFactory(bool resetCache)
{
ResetCache = resetCache;
}
public ISATService GetSATService()
{
if (DataStore.Questions == null || ResetCache)
return new ServiceWrapper();
else
return new FakeService();
}
}
Hope this helps. Good luck!
when you say fake the call, are you just testing the client side?
you could use fiddler, intercept the request and return the local xml file to the client. No messing around with your client code then.
To elaborate on Audie's answer
Using DI would get you what you want. Very simply you would create an interface that your real object and your mock object both implement
public interface IFoo
{}
Then you would have your GetSATService method return either a MockSATSerivce or the real SATService object based on your needs.
This is where you would use a DI container (some object that stores interface to concrete type mappings) You would bootstrap the container with the types you want. So, for a unit test, you could contrstruct a mock container that registers the MockSATService as the implementer of the IFoo interface.
Then you would as the container for the concrete type but interface
IFoo mySATService = Container.Resolve<IFoo>();
Then at runtime you would just change out the container so that it bootstraps with the runtime types instead of the mock types but you code would stay the same (Because you are treating everything as IFoo instead SATService)
Does that make sense?
Over time I found that an interesting way to do this is by extracting an interface and creating a wrapper class. This adapts well to a IoC container and also works fine without one.
When testing, create the class passing a fake service. When using it normally, just call the empty constructor, which might simply construct a provider or resolve one using a config file.
public DataService : IDataService
{
private IDataService _provider;
public DataService()
{
_provider = new RealService();
}
public DataService(IDataService provider)
{
_provider = provider;
}
public object GetAllQuestions()
{
return _provider.GetAllQuestions();
}
}

Categories