Multithread Singeleton Substitution with NSubstitute - c#

I have a public method ValidateWords inside FooService.To test the ValidateWord method, I created IAppSettingWrapper and AppSettingWrapper which returns the Instance of AppSettings.
Inside the test method, I want to substitute NotAllowedWords using NSubstitute. However, it throws an object reference exception. Is there any way for substitution? If it's not possible, how can I refactor my static instance?
public sealed class AppSettings
{
private static object _lockObject = new object();
private static volatile AppSettings? _instance;
private static DateTime _cacheTime;
private Settings[] _settings;
public AppSettings()
{
try
{
_settings = GetSettings();
}
catch { }
}
public static AppSettings Instance
{
get
{
lock (_lockObject)
{
if (_instance == null)
{
_instance = new AppSettings();
}
}
return _instance;
}
}
public List<string> NotAllowedWords
{
get
{
return new List<string>() {
"index",
"change"
};
}
}
public T GetValues<T>(string key,T defaultValue)
{
T result = defaultValue;
var settings = _settings.Where(i => i.Key == key).FirstOrDefault();
result = (T)Convert.ChangeType(settings.Value, typeof(T));
return result;
}
private Settings[]? GetSettings()
{
//gets data from web services
return base.Channel.GetSettings();
}
}
public class Settings
{
public string Key { get; set; }
public string Value { get; set; }
}
public interface IAppSettingsWrapper
{
public AppSettings Instance();
}
public class AppSettingsWrapper : IAppSettingsWrapper
{
public AppSettings Instance()
{
return AppSettings.Instance;
}
}
[TestClass]
public class FooServiceTest{
private IAppSettingsWrapper _appSettingsWrapper;
[TestInitialize]
public void TestInitialize(IAppSettingsWrapper appSettingsWrapper)
{
_appSettingsWrapper = Substitute.For<IAppSettingsWrapper>();
}
private FooService CreateFooService()
{
return new FooService(_appSettingsWrapper);
}
[TestMethod]
public void Throw_Exception_When_Given_Word_Not_Allowed() {
var service = this.CreateFooService();
_appSettingsWrapper.Instance().NotAllowedWords.Returns(new List<string> { "index" });
var word = "index";
Exception ex = Assert.ThrowsException<Exception>(() => service.ValidateWords(word));
Assert.AreEqual("this word is not allowed", ex.Message);
}
}
public class FooService
{
private IAppSettingsWrapper _appSettingsWrapper;
public FooService(IAppSettingsWrapper appSettingsWrapper)
{
_appSettingsWrapper = appSettingsWrapper;
}
public void ValidateWords(string word)
{
if (_appSettingsWrapper.Instance().NotAllowedWords.Contains(word))
{
throw new Exception("this word is not allowed");
}
}
}

The AppSettings.NotAllowedWords property is not substitutable due to it not being virtual and the class being sealed. If you add NSubstitute.Analyzers to your test project it will help you find these cases. (The How NSubstitute Works documentation outlines why this is the case.)
One option is to make AppSettings implement an IAppSettings interface and inject that into FooService (rather than the wrapper). Then you can use a substitute for tests, and AppSettings.Instance for your real code.

Related

How to inject depdency while mocking protected method using AutoMock XNnit?

In the below code snippet, I am trying to mock the response of a protected method and test the response of the public method which calls the protected method. The protected method calls an external API, hence I would like to mock the response in order to test the public method which calls the protected method.
The problem arises when I try to inject the dependency on the class which is used by the public method. It always goes to the default constructor ignoring the dependency objects I pass. Please let me know where I am missing the change.
Note: I have added the default constructor just to understand the flow. I will not have it in the real implementation.
Test Method
[Fact]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
Depdency1 depdency1 = new Depdency1();
Depdency2 depdency2 = new Depdency2();
var parm1 = new NamedParameter("dependency1", depdency1);
var parm2 = new NamedParameter("dependency2", depdency2);
//Mock the protected method
mock.Mock<SystemUnderTest>(parm1, parm2)
.Protected()
.Setup<bool>("IsOrderValid", "TestOrder")
.Returns(true);
var sut = mock.Create<SystemUnderTest>();
sut.ProcessOrder("Test");
}
}
Main class
public class SystemUnderTest : ISystemUnderTest
{
private readonly IDependency1 _dependency1;
private readonly IDependency2 _dependency2;
public SystemUnderTest()
{
}
public SystemUnderTest(IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1 = dependency1;
_dependency2 = dependency2;
}
public bool ProcessOrder(string OrderID)
{
//Businss logic using dependency1
if (IsOrderValid(OrderID))
{
if (_dependency1 == null)
{
throw new AggregateException("Depdency1 is null");
}
//Businss logic
return true;
}
else
{
if (_dependency1 == null)
{
throw new AggregateException("Depdency1 is null");
}
//Businss logic
return false;
}
}
protected virtual bool IsOrderValid(string OrderID)
{
//Business logic using dependency2
if (_dependency2 == null)
{
throw new AggregateException("Depdency2 is null");
}
return true; //False based on logic
}
}
public interface IDependency1
{
void Method1();
}
public interface IDependency2
{
void Method2();
}
public class Depdency1 : IDependency1
{
private int _property1;
public void Method1()
{
throw new NotImplementedException();
}
}
public class Depdency2 : IDependency2
{
private int _property2;
public void Method2()
{
throw new NotImplementedException();
}
}

Is it possible to create a Singleton factory class maintaining a dictionary for instances?

I have multiple classes that inherit from IPrint. I want to instantiate these classes using a factory but I want to maintain a single instance of each type.
Is this possible?
Please find my sample code below.
public interface IPrint
{
void DoPrint();
}
public class DigitalPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class InkPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class PrintFactory
{
private static IDictionary<IPrint, object> prints = new
Dictionary<IPrint, object>();
private PrintFactory()
{
}
public static IPrint GetPrint(PrintType type)
{
// return instance depending on type. Instantiate only once
//like singleton
// How to write so that it returns a single instance depending
//on type
return null;
}
}
public enum PrintType
{
DigitalPrint,
InkPrint
}
Can someone give me some idea if this is possible?
Thanks.
You can create IPrint instances when initializing Dictionary<PrintType, IPrint>:
private static IDictionary<PrintType, IPrint> prints =
new Dictionary<PrintType, IPrint> {
{ PrintType.DigitalPrint, new DigitalPrint() },
{ PrintType.InkPrint, new InkPrint() }
};
Getting print (thus print is a class, the same instance will be returned for each request):
public static IPrint GetPrint(PrintType type)
{
IPrint print;
if (!prints.TryGetValue(type, out print))
return null;
return print;
}
If you don't want to create IPrint instances until the client asks for them, you can use Dictionary<PrintType, Lazy<IPrint>>:
private static IDictionary<string, Lazy<IPrint>> prints =
new Dictionary<string, Lazy<IPrint>> {
{ PrintType.DigitalPrint, new Lazy<IPrint>(() => new DigitalPrint()) },
{ PrintType.InkPrint, new Lazy<IPrint>(() => new InkPrint()) }
};
Getting print (in this case only one instance of each IPrint type will be created, but not before someone tries to get the instance of that type):
public static IPrint GetPrint(PrintType type)
{
Lazy<IPrint> factory;
if (!prints.TryGetValue(type, out factory))
return null;
return factory.Value;
}
Though I would consider using dependency injection framework instead of implementing such functionality manually.
Further reading: Ninject or Autofac
Yes, it's possible.
This creates the IPrint's before they're needed. You could make them lazily created, instead.
public class Program
{
public static void Main(string[] args)
{
var factory = new PrintFactory();
Console.WriteLine(PrintFactory.GetPrint(PrintType.DigitalPrint));
Console.WriteLine(PrintFactory.GetPrint(PrintType.InkPrint));
}
}
public interface IPrint
{
void DoPrint();
}
public class DigitalPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class InkPrint : IPrint
{
public void DoPrint()
{
// logic
}
}
public class PrintFactory
{
// Make the dictionary from PrintType to IPrint instead of IPrint to object
private static IDictionary<PrintType, IPrint> prints = new Dictionary<PrintType, IPrint>();
// Initialize prints in a static constructor.
static PrintFactory()
{
prints.Add(PrintType.DigitalPrint, new DigitalPrint());
prints.Add(PrintType.InkPrint, new InkPrint());
}
public static IPrint GetPrint(PrintType type)
{
if (!prints.ContainsKey(type))
{
// TODO: Maybe throw an exception or log?
}
return prints[type];
}
}
public enum PrintType
{
DigitalPrint,
InkPrint
}
I would get rid of the enum and make a generic method:
public static IPrint GetPrint<T>() where T : IPrint, new ()
{
foreach (var key in prints.Keys) {
if (key is T)
return null;
}
return new T();
}

Moq an object in a static class

I can't get Moq to mock an object that gets created in a static method.
Here is my moq and code
code:
public interface IConfigHelper
{
string GetConfiguration(string sectionName, string elementName);
}
public class ConfigHelper : IConfigHelper
{
public ConfigHelper() { }
public virtual string GetConfiguration(string sectionName, string elementName)
{
string retValue = String.Empty;
//Does things to get configuration and return a value
return retValue;
}
}
public class myRealClass
{
public myRealClass(){}
public string myworkingMethod()
{
var retValue = String.Empty;
retValue = utilSvc.GetConfigurationValue();
return retValue;
}
}
public static class utilSvc
{
public static string GetConfigurationValue()
{
ConfigHelper configUtil = new ConfigHelper(); //NOT BEING MOCKED
return configUtil.GetConfiguration("sectionName/sectionElement", "ClinicalSystem");
}
}
the Test using Moq
[TestFixture(TestName = "Tests")]
public class Tests
{
private Mock<IConfigHelper> configHelperMOCK;
[SetUp]
public void Setup()
{
configHelperMOCK = new Mock<IConfigHelper>();
}
[Test]
public void serviceIsBPManagementForValidSource()
{
//Arrange
string sectionName = "sectionName/sectionElement";
string clinicalElementName = "ClinicalSystem";
string clinicalElementValue = "Zedmed";
configHelperMOCK.Setup(s => s.GetConfiguration(sectionName, clinicalElementName)).Returns(clinicalElementValue);
//act
// the call to myRealClass
//assert
// test assertions
}
}
The issue that I am having is with this line:
ConfigHelper configUtil = new ConfigHelper(); //NOT BEING MOCKED
I cannot get the moq to Mock the object.
I do not want the code to read the config file. I wish to moq away this instance of ConfigHelper
You can't wrap the static class/method but you can redirect it
public static class UtilSvc
{
static UtilSvc()
{
CreatorFunc = () => new ConfigHelper();
}
public static Func<IConfigHelper> CreatorFunc { get; set; }
public static string GetConfigurationValue()
{
var configUtil = CreatorFunc();
return configUtil.GetConfiguration("sectionName/sectionElement",
"ClinicalSystem");
}
}
and then in the test
//...
private Mock<IConfigHelper> configHelperMOCK;
[SetUp]
public void Setup()
{
configHelperMOCK = new Mock<IConfigHelper>();
UtilService.CreatorFunc = () => configHelperMOCK.Object;
}
//...
You cannot mock static class. I would rather propose to inject that IConfigHelper into the myRealClass. That is the usual way how to decouple dependencies and use DI.
public class myRealClass
{
private IConfigHelper _configHelper;
public myRealClass(IConfigHelper configHelper)
{
_configHelper = configHelper;
}
public string myworkingMethod()
{
var retValue = String.Empty;
retValue = _configHelper.GetConfigurationValue();
return retValue;
}
}
Avoid coupling your code to static classes, which in most cases cause you code be to difficult to maintain and test.
Follow the Explicit Dependencies Principle
Methods and classes should explicitly require (typically through
method parameters or constructor parameters) any collaborating objects
they need in order to function correctly.
Give the article a read. It is short and very informative.
If you want to keep the static class then you wrap the static class behind an abstraction.
public interface IUtilSvc {
string GetConfigurationValue();
}
public class utilSvcWrapper : IUtilSvc {
public string GetConfigurationValue() {
return utilSvc.GetConfigurationValue(); //Calling static service
}
}
Or another option is that utlSvc does not have to be static if can be injected into dependent classes
public class utilSvc : IUtilScv {
private readonly IConfigHelper configUtil;
public utilSvc(IConfigHelper configHelper) {
configUtil = configHelper;
}
public string GetConfigurationValue() {
return configUtil.GetConfiguration("sectionName/sectionElement", "ClinicalSystem");
}
}
Inject the IUtilScv into the dependent class so that it is no longer dependent on static class.
public class myRealClass {
private readonly IUtilScv utilSvc;
//Explicit dependency inject via constructor
public myRealClass(IUtilScv utilSvc) {
this.utilSvc = utilSvc;
}
public string myworkingMethod() {
var retValue = utilSvc.GetConfiguration();
return retValue;
}
}
In that case you don't even need IConfigHelper when testing as it has also been abstracted away. And you only need to mock the dependencies needed for the test.
[TestFixture(TestName = "Tests")]
public class Tests {
private Mock<IUtilScv> utilScvMOCK;
[SetUp]
public void Setup() {
utilScvMOCK = new Mock<IUtilScv>();
}
[Test]
public void serviceIsBPManagementForValidSource() {
//Arrange
var expectedClinicalElementValue = "Zedmed";
utilScvMOCK
.Setup(s => s.GetConfiguration())
.Returns(expectedClinicalElementValue)
.Verifiable();
var sut = new myRealClass(utilScvMOCK.Object);
//Act
var actualClinicalElementValue = sut.myworkingMethod();
//Assert
configHelperMOCK.Verify();
Assert.AreEqual(expectedClinicalElementValue, actualClinicalElementValue);
}
}

WCF Custom OperationConext Lifetimemanager for EF DbContext

container.RegisterType<IDataContextFactory<MyDataContext>, DefaultDataContextFactory<MyDataContext>>(new PerRequestLifetimeManager());
Created a PerRequestLifetimeManager using OperationContext but it does not seem call setValue function at all, it always trys to go to GetValue() function which always retruns null since nothing has been set.
My goal is to create a lifetimeManager for dbconetxt that will give me a new dbContext per method call. transient is not an option since it won;t work for join query.
public class WcfOperationContext : IExtension<OperationContext>
{
private readonly IDictionary<string, object> items;
private WcfOperationContext()
{
items = new Dictionary<string, object>();
}
public IDictionary<string, object> Items
{
get { return items; }
}
public static WcfOperationContext Current
{
get
{
WcfOperationContext context = OperationContext.Current.Extensions.Find<WcfOperationContext>();
if (context == null)
{
context = new WcfOperationContext();
OperationContext.Current.Extensions.Add(context);
}
return context;
}
}
public void Attach(OperationContext owner) { }
public void Detach(OperationContext owner) { }
}
public class PerRequestLifetimeManager : LifetimeManager
{
private string key;
public PerRequestLifetimeManager()
{
key = Guid.NewGuid().ToString();
}
public override object GetValue()
{
if (WcfOperationContext.Current == null)
{
return null;
}
else
{
return WcfOperationContext.Current.Items[key];
}
}
public override void RemoveValue()
{
if (WcfOperationContext.Current != null)
{
WcfOperationContext.Current.Items.Remove(key);
}
}
public override void SetValue(object newValue)
{
if (WcfOperationContext.Current != null)
{
WcfOperationContext.Current.Items.Add(key, newValue);
}
}
}
My solution for this was to use this nuget package: UnityWCF
The Service should be instantiated by Unity and new instance per call.
For this use this settings on the service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ...
Inject DbContext where you need. And register in Unity like this:
container.RegisterType<DbContext, YourDbContext>(new HierarchicalLifetimeManager(), ...);

Change dependencies of existing object

I am working on WPF application.
I use StructureMap to inject dependencies.
There are some service layer classes exist that they give parameter from constructor.
The value that I pass to constructor will change run time.
Presentation layer's classes use services to present data for user. Whenever value has changed I inject service again with new value. But active instance of presentation layer returns previous value.
I've prepared simple example for better understanding.
// static class that keeps some value
public class ValueKeeper
{
public static string Value { get; set; }
}
public interface IService
{
string Value { get; set; }
}
// Service layer class
public class Service : IService
{
// default constructor
public Service(string value)
{
Value = value;
}
#region IService Members
public string Value { get; set; }
#endregion
}
public class Program
{
private readonly IService _service;
//injecting service class
public Program(IService service)
{
_service = service;
}
// structuremap configuration
private static void Config()
{
ObjectFactory.Initialize(x => x.Scan(scanner =>
{
scanner.TheCallingAssembly();
scanner.WithDefaultConventions();
x.For<IService>().CacheBy(InstanceScope.Hybrid).Use(() =>
{
var service = new Service("value1");
return service;
});
}));
}
// structuremap configuration after value changed.
private static void ReConfig()
{
ObjectFactory.Configure(x => x.Scan(scanner =>
{
x.For<IService>().CacheBy(InstanceScope.Hybrid).Use(() =>
{
var service =new Service(ValueKeeper.Value);
return service;
});
}));
}
private string PresentationMethod()
{
return _service.Value;
}
private static void Main(string[] args)
{
Config(); // Firtst time injecting dependencies
var prog = ObjectFactory.GetInstance<Program>();
Console.WriteLine(prog.PresentationMethod()); // returns "value1"
ValueKeeper.Value = "value 2"; //changing static property
ReConfig(); // reconfig service class with new property
Console.WriteLine(prog.PresentationMethod()); // it returns value1 but I expect value2 .
Console.ReadKey();
}
}
Real application contains many presentation and service classes.
How can I change live service instances with new object and value ?
Update :
I saw this link. It seems by using Setter Injection it's possible to change existing object.
Is setter injection my solution ?
You could use the strategy pattern to easily keep track of and switch between instances of the same interface at runtime. Here is a quick example:
var container = new Container(x => x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.AddAllTypesOf<IDiscountCalculator>();
}));
var strategy = container.GetInstance<IDiscountStrategy>();
Console.WriteLine(strategy.GetDiscount("Regular", 10)); // 0
Console.WriteLine(strategy.GetDiscount("Normal", 10)); // 1
Console.WriteLine(strategy.GetDiscount("Special", 10)); // 5
which depends on the following types:
public interface IDiscountStrategy
{
decimal GetDiscount(string userType, decimal orderTotal);
}
public class DiscountStrategy : IDiscountStrategy
{
private readonly IDiscountCalculator[] _discountCalculators;
public DiscountStrategy(IDiscountCalculator[] discountCalculators)
{
_discountCalculators = discountCalculators;
}
public decimal GetDiscount(string userType, decimal orderTotal)
{
var calculator = _discountCalculators.FirstOrDefault(x => x.AppliesTo(userType));
if (calculator == null) return 0;
return calculator.CalculateDiscount(orderTotal);
}
}
public interface IDiscountCalculator
{
bool AppliesTo(string userType);
decimal CalculateDiscount(decimal orderTotal);
}
public class NormalUserDiscountCalculator : IDiscountCalculator
{
public bool AppliesTo(string userType)
{
return userType == "Normal";
}
public decimal CalculateDiscount(decimal orderTotal)
{
return orderTotal * 0.1m;
}
}
public class SpecialUserDiscountCalculator : IDiscountCalculator
{
public bool AppliesTo(string userType)
{
return userType == "Special";
}
public decimal CalculateDiscount(decimal orderTotal)
{
return orderTotal * 0.5m;
}
}
Or, if you have short lived dependencies that you want to dispose of right away, you should inject an abstract factory to create them on demand.
public ISomeObjectFactory
{
ISomeObject Create();
void Release(ISomeObject someObject);
}
public class SomeObjectFactory
: ISomeObjectFactory
{
//private readonly IAclModule aclModule;
// Inject dependencies at application startup here
//public SiteMapPluginProviderFactory(
// IAclModule aclModule
// )
//{
// if (aclModule == null)
// throw new ArgumentNullException("aclModule");
//
// this.aclModule = aclModule;
//}
public ISomeObject Create(IState state)
{
return new SomeObject(state);
// return new SomeObject(state, this.aclModule);
}
pubic void Release(ISomeObject someObject)
{
var disposable = someObject as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
And then use like:
public class Consumer : IConsumer
{
private readonly ISomeObjectFactory someObjectFactory;
public Consumer(ISomeObjectFactory someObjectFactory)
{
if (someObjectFactory == null)
throw new ArgumentNullException("someObjectFactory");
this.someObjectFactory = someObjectFactory;
}
public void DoSomething(IState state)
{
var instance = this.someObjectFactory.Create(state);
try
{
// Use the instance here.
}
finally
{
this.someObjectFactory.Release(instance);
}
}
}
Although not shown here, the factory could switch between different classes if needed, or you could pass a different dependency (the IState in this example) to the same type of class when it is created.
Service Locator is Anti-Pattern and should be avoided in all but the rarest of circumstances.

Categories

Resources