I have the following method signature in an interface:
public interface ISettingsUtil
{
T GetConfig<T>(string setting, dynamic settings);
}
Which I have attempted to mock:
var settingsUtil = Substitute.For<ISettingsUtil>();
var maxImageSize = settingsUtil.GetConfig<long>("maxImageSize",
Arg.Any<dynamic>()).Returns(100L);
This throws a Microsoft.CSharp.RuntimeBinder.RuntimeBinderException exception on the 2nd line:
'long' does not contain a definition for 'Returns'
Any thoughts on how to mock T GetConfig<T>(string setting, dynamic settings) correctly?
For anyone still struggling with this, you can actually mock dynamics in NSubsitute, it just requires jumping through some minor hoops.
See the below case of mocking out calls to a signalR client hub.
The important line is this one:
SubstituteExtensions.Returns(_hubContext.Clients.All, _mockClient);
In order to mock the dynamic I have created an interface with the methods I want to listen for. You then need to use SubstituteExtensions.Returns rather than simply chaining a .Returns at the end of the object.
If you don't need to verify anything you could also use an anonymous object.
Full code sample follows:
[TestFixture]
public class FooHubFixture
{
private IConnectionManager _connectionManager;
private IHubContext _hubContext;
private IMockClient _mockClient;
[SetUp]
public void SetUp()
{
_hubContext = Substitute.For<IHubContext>();
_connectionManager = Substitute.For<IConnectionManager>();
_connectionManager.GetHubContext<FooHub>().Returns(_hubContext);
_mockClient = Substitute.For<IMockClient>();
SubstituteExtensions.Returns(_hubContext.Clients.All, _mockClient);
}
[Test]
public void PushFooUpdateToHub_CallsUpdateFooOnHubClients()
{
var fooDto = new FooDto();
var hub = new FooHub(_connectionManager);
hub.PushFooUpdateToHub(fooDto);
_mockClient.Received().updateFoo(fooDto);
}
public interface IMockClient
{
void updateFoo(object val);
}
}
public class FooHub : Hub
{
private readonly IConnectionManager _connectionManager;
public FooHub(IConnectionManager connectionManager)
{
_connectionManager = connectionManager;
}
public void PushFooUpdateToHub(FooDto fooDto)
{
var context = _connectionManager.GetHubContext<FooHub>();
context.Clients.All.updateFoo(fooDto);
}
}
NSubstitute does not work with members that use dynamic. (Github issue)
Related
I have a concrete class CalculatorService of which I want to test CalculateBuyOrder() method. CalculatorService has several dependencies injected through constructor parameters and CalculateBuyOrder() calls another method on the same service.
I need a mock of the class that
Can be created without parameterless constructor (i.e., automatically mocking the dependency tree).
Has all methods mocked (stubbed) by default, with the option of overriding and calling the real implementation on one (or several) methods.
It seems such an obvious and basic use case, but I can't seem to neither figure it out myself nor find the documentation that explains it. The furthest I've gotten is using AutoMocker for achieving 1., but 2. has me stumped.
public class CalculatorService
: ICalculatorService
{
private readonly IMainDbContext _db;
private readonly TradeConfig _tradeConfig;
private readonly MainConfig _config;
private readonly StateConfig _state;
private readonly ICurrencyService _currencyService;
private readonly IExchangeClientService _client;
// Parameters need to be mocked
public CalculatorService(MainDbContext db, TradeConfig tradeConfig, MainConfig config, StateConfig state, ICurrencyService currencyService, IExchangeClientService client)
{
this._db = db;
this._tradeConfig = tradeConfig;
this._config = config;
this._state = state;
this._currencyService = currencyService;
this._client = client;
}
// This needs to be tested
public async Task<OrderDto> CalculateBuyOrder(
String coin,
CoinPriceDto currentPrice,
Decimal owned,
IDictionary<TradeDirection, OrderDto> lastOrders,
OrderDto existingOrder = null,
TradeConfig.TradeCurrencyConfig tradingTarget = null,
Decimal? invested = null)
{
// ...
this.GetInvested();
// ...
}
// This needs to be mocked
public virtual IDictionary<String, Decimal> GetInvested()
{
// ...
}
}
}
As some of the comments have said you should place interfaces in your constructor as for an example pseudo code:
public class Foo : IFoo
{
IBoo boo;
IGoo goo;
public Foo(IBoo boo, IGoo goo)
{
this.boo = boo;
this.goo = goo;
}
public int MethodToTest(int num1,int num2)
{
//some code
/*..*/ = boo.Method(num1,num2);
//more code and return
}
}
notice all the parameters in the constructor are interfaces.
and then your test method would look a little like this
[TestMethod]
public void TestMethod()
{
//setting up test
var boo = new Mock<IBoo>();
var goo = new Mock<IGoo>();
var foo = new Foo(boo.object,goo.object);
boo.Setup(x=>x.Method(1,2)).Returns(10);
//running test
var result = foo.MethodToTest(1,2);
//verify the test
Assert.AreEqual(12,result);
}
For more information just go to this link Moq Github.
Now for the second part of your question, mocking a method within the same class. This defeats the purpose of mocking, as mocking is to "fake" dependencies. So either restructure the code so you can mock it properly, or make sure any methods it calls are mocked in a way they'll give a reliable output that you can use.
I am trying to test the behavior of a class, when it's passed one stub object via a delegate factory. I made a version of the test in which all the class's dependencies (except the factory) are passed as Mock objects and it works as supposed to. Now I am trying to use AutoMock to get the container to automatically create the mocks.
I am having issues passing concrete values for the delegate factory in the constructor in ClassUnderTest using mock.Provide(). (like this comment suggests)
Class that I am testing:
public ClassUnderTest
{
private readonly firstField;
private readonly Func<string, ISecondField, IThirdField, IResultField> resultFieldFactory;
private int someCounter = -1;
public ClassUnderTest(IFirstField firstField, Func<string, ISecondField, IThirdField, IResultField> resultFieldFactory )
{
this.firstField = firstField;
this.resultFieldFactory= resultFieldFactory;
}
public methodToTest()
{
IResultField resultField = resultFieldFactory(someString, secondFieldValue, thirdFieldValue);
resultField.AddToList();
}
}
Business logic module :
public class BusinessLogicModule: Module
{
//some other things that work
builder.RegisterType<ClassUnderTest>().As<IClassUnderTest>();
builder.RegisterType<SecondField>().As<ISecondField>();
builder.RegisterType<ThirdField>().As<IThirdField>();
builder.RegisterType<ResultField>().As<IResultField>();
}
Test class:
[TestClass]
public class TestClass()
{
private IFirstField firstField;
private Func<string, ISecondField, IThirdField, IResultField> funcToTriggerIResultFieldFactory;
[TestInitialize]
public void Setup()
{
this.firstField= Resolve<IFirstField>();
this.secondField= Resolve<ISecondField>();
this.funcToTriggerIResultFieldFactory = Resolve<Func<string, ISecondField, IThirdField, IResultField>>();
}
[TestMethod]
public void testMethodWithAutoMock()
{
using (var automock = AutoMock.GetLoose())
{
//trying to setup the SUT to get passed a "concrete" object
autoMock.Provide(funcToTriggerIResultFieldFactory(stringValue, secondFieldValue, thirdFieldValue));
var sut = autoMock.Create<IClassUnderTest>;
sut.MethodToTest();
//asserts
}
}
}
I would be grateful for any indication on what I am doing wrong. What am I missing? How could it be fixed? Is it a simple syntax fix or is something wrong with my approach to this test?
Thanks in advance for your time.
In your example, when you call autoMock.Provide() you are not passing in you factory function, but you are invoking the factory function and passing in the result (IResultField). To fix this, call
autoMock.Provide(funcToTriggerIResultFieldFactory);
Here is a full example of registering a function with the auto mocking container.
I have a helper class which inherits from an Interface and has three dependencies.
public class StudentHelper : IStudentHelper
{
private readonly IUpdateStudentManager _updateStudentManager;
private readonly ISchedulerHelper _schedulerHelper;
public StudentHelper(
IUpdateStudentManager updateStudentManager,
ISchedulerHelper schedulerHelper)
{
_updateStudentManager = updateStudentManager;
_schedulerHelper = schedulerHelper;
}
// Rest of the class not shown here for brevity.
}
To test this I wrote a test class like so:
[TestClass]
public class StudentHelperTests
{
private Mock<StudentHelper> _studentHelperMock;
private Mock<IUpdateStudentManager> _updateStudentManagerMock;
private Mock<ISchedulerHelper> _schedulerHelperMock;
[TestInitialize]
public void Setup()
{
_updateStudentManagerMock = new Mock<IUpdateStudentManager>();
_schedulerHelperMock = new Mock<ISchedulerHelper>();
_studentHelperMock = new Mock<StudentHelper>(_updateStudentManagerMock.Object,
_schedulerHelperMock.Object);
}
[TestMethod]
public void Calling_GetEndDate_Returns_A_FutureDate()
{
_productRulesHelper.Setup(x=>x.GetEndDate(DateTime.UtcNow.ToShortDateString(),1)).Returns(DateTime.UtcNow.AddYears(1).ToString("MM/dd/yyyy"));
_productRulesHelper.VerifyAll();
}
}
The method to test returns this error:
Test method StudentHelperTests.Calling_GetEndDate_Returns_A_FutureDate
threw exception:
System.NotSupportedException: Invalid setup on a non-virtual
(overridable in VB) member: x =>
x.GetEndDate(DateTime.UtcNow.ToShortDateString(), 1)
The GetEndDate method just takes in a date as string, adds a year and returns the resulting date as string.
I think the way StudentHelperMock is initialized is not correct!!!
Can someone please guide me on this?
Thanks in advance.
You're not supposed to create a mock for the instance you're trying to test - you're supposed to create a mock for its dependencies.
The purpose of mocking is to isolate the system under test (StudentHelper) from its dependencies (IUpdateStudentManager, ISchedulerHelper) by replacing them with test doubles (e.g. mocks).
Here's what your test case should look like:
[TestMethod]
public void Calling_GetEndDate_Returns_A_FutureDate()
{
// Arrange
var helper = new StudentHelper(_updateStudentManagerMock.Object, _schedulerHelperMock.Object);
var now = DateTime.UtcNow;
// Act
var result = x.GetEndDate(now.ToShortDateString(),1);
// Assert
Assert.Equal(now.AddYears(1).ToString("MM/dd/yyyy"), result);
}
On a side note: I would also advise against the usage of global test setups. See: Why you should not use SetUp and TearDown in NUnit.
Related reading:
The Little Mocker by Uncle Bob
When to Mock by Uncle Bob
Try something like this:
[TestClass]
public class StudentHelperTests
{
private StudentHelper _objectToTest;
private Mock<IUpdateStudentManager> _updateStudentManagerMock;
private Mock<ISchedulerHelper> _schedulerHelperMock;
[TestInitialize]
public void Setup()
{
_updateStudentManagerMock = new Mock<IUpdateStudentManager>();
_schedulerHelperMock = new Mock<ISchedulerHelper>();
_studentHelperMock = StudentHelper(_updateStudentManagerMock.Object,
_schedulerHelperMock.Object);
}
[TestMethod]
public void Calling_GetEndDate_Returns_A_FutureDate()
{
// The method name says:
var retrievedDate = _objectToTest.GetEndDate();
Assert()//... And you should verify than the retrieved date is "a future date"
}
}
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());
}
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();
}
}