Using Nsubstitute for mocking but getting an error - c#

I am new to unit testing, so pardon me if I am unable to explain this question properly. I am reading a book "The art of Unit Testing 2nd Edition" and trying to implement unit testing in my project. I am currently stuck or confused when testing using mocking (using NSubstitute as the mocking framework).
Here is my scenario:
I have two interfaces ICommand and IUser
public interface ICommand
{
string execute();
}
public interface IUserCalendar
{
string LoadCalendar();
}
I have a class LoadCalendar which implements ICommand:
public class LoadCalendar : ICommand
{
private IUserCalendar user;
public string execute()
{
return this.user.LoadCalendar();
}
public LoadCalendar(IUserCalendar obj)
{
this.user = obj;
}
}
ViewCalendar implements IUserCalendar:
public class Viewer : IUserCalendar
{
public string LoadCalendar()
{
return "Viewer Load Calendar Called";
}
}
Using an agent class I am invoking command for specific request. (Here I am showing only one request LoadCalendar for one user viewer but I have more command and more users)
My client has an invoker object that invokes the command for specific user.
public class Client
{
public Client()
{ }
public string LoadCalendar(ICommand cmd)
{
Invoker invoker = new Invoker(cmd);
return invoker.execute();
}
}
Now I like to test the client class that when it calls for specific user it should return proper object or message.
[Test]
public void client_Load_Calendar_Administrator()
{
IUserCalendar calanedar = Substitute.For<IUserCalendar>();
ICommand cmd = Substitute.For<ICommand>(calanedar);
Client c = new Client();
c.LoadCalendar(cmd, calanedar).Returns(Arg.Any<string>());
}
I don't know where I am doing wrong and it's throwing an error.
NSubstitute.Exceptions.SubstituteException : Can not provide constructor arguments when substituting for an interface.
Any help is really appreciated. Sorry for long question.

The error you're getting:
Can not provide constructor arguments when substituting for an interface.
Is telling you exactly what's wrong.
You're passing in constructor arguments here:
ICommand cmd = Substitute.For<ICommand>(calanedar);
Of course, interfaces never have a constructor. You're trying to interact with your ICommand interface as if it were your concrete LoadCalendar implementation of it.
Furthermore, to be able to unit test a class you always want to have a default (parameterless) constructor. Many mocking frameworks actually require this.
In this case you should probably test against the concrete class and mock/substitute the classes that it uses.
Either that, or you only substitute ICommand simply to have it return a pre-set (string) value. Then you can proceed to verify if the code that consumes your command, actually invokes it and/or does the correct thing with the value it returns.
To illustrate:
[Test]
public void client_Load_Calendar_Administrator()
{
// You are substituting (mocking) the IUserCalendar here, so to test your command
// use the actual implementation
IUserCalendar calendar = Substitute.For<IUserCalendar>();
ICommand cmd = new LoadCalendar(calendar):
// Let the IUserCalendar.LoadCalendar() return a certain string
// Then Assert/Verify that cmd.Execute() returns that same string
}
That's the point of unit testing: you test the smallest piece of functionality by mocking all dependencies. Otherwise it's an integration test.
To test your client:
[Test]
public void client_Load_Calendar_Administrator()
{
ICommand cmd = Substitute.For<ICommand>();
Client c = new Client();
// Let your command return a certain string
// Then verify that your calendar returns that same string
}
EDIT: In case you're interested, the method in NSubstitute that throws this exception:
private void VerifyNoConstructorArgumentsGivenForInterface(object[] constructorArguments)
{
if (constructorArguments != null && constructorArguments.Length > 0)
{
throw new SubstituteException("Can not provide constructor arguments when substituting for an interface.");
}
}
They're pretty clear about it: no constructor arguments for an interface substitute, no matter what.

Related

How to Mock Base Class Property or Method in C#

i surf over internet for mock base class member in Nunit test case with no luck and finally decide to ask this scrap to stack overflow community.
Below code snippet has scenario in my application. i am going to write unit test for BankIntegrationController class and i want to make stub data or make mock for IsValid property and Print method.
Fremwork : Moq,Nunit
public class CController : IController
{
public bool IsValid {get;set;}
public string Print()
{
return // some stuff here;
}
}
public class BankIntegrationController : CController, IBankIntegration
{
public object Show()
{
if(this.IsValid)
{
var somevar = this.Print();
}
return; //some object
}
}
You don't need to mock anything. Just set the property before calling Show:
[Fact]
public void Show_Valid()
{
var controller = new BankIntegrationController { Valid = true };
// Any other set up here...
var result = controller.Show();
// Assertions about the result
}
[Fact]
public void Show_Invalid()
{
var controller = new BankIntegrationController { Valid = false };
// Any other set up here...
var result = controller.Show();
// Assertions about the result
}
Mocking is a really valuable technique when you want to specify how a dependency would behave in a particular scenario (and particularly when you want to validate how your code interacts with it), but in this situation you don't have any dependencies (that you've shown us). I've observed a lot of developers reaching for mocks unnecessarily, in three situations:
When there's no dependency (or other abstract behaviour) involved, like this case
When a hand-written fake implementation would lead to simpler tests
When an existing concrete implementation would be easier to use. (For example, you'd rarely need to mock IList<T> - just pass in a List<T> in your tests.)

How do I unit test a class that relies on HttpContext.GetGlobalResourceObject?

I'm trying to add tests to a webforms project. There's a static method to grab lines from resource files. One of the classes I'm trying to test, relies on grabbing text from the resource file.
public static class MyStaticClass {
public static string getText(String name)
{
String s = HttpContext.GetGlobalResourceObject("MyResources", name).ToString();
return s;
}
}
public class ClassUnderTest
{
// returns: "Hey it's my text"
private string _eg = MyStaticClass.getText("label_in_resources.resx_file")
}
class UnitTests
{
[Test]
public void TestMyClass()
{
ClassUnderTest _cut = new ClassUnderTest();
// errors out because ClassUnderTest utilizes getText
// which requires HttpContext.GetGlobalResourceObject
// ... other stuff
}
}
Note: these are simplistic examples.
The issue is that I get a Test Failed with the message:
Message: System.NullReferenceException : Object reference not set to an instance of an object.
With my sleuthing, I've determined that this is because HttpContext is null during these tests.
I've looked at quite a few SO posts on mocking HttpContext but I don't think that I fully understand what exactly they're doing as they're typically dealing with MVC and not Webforms. Still most of them use HttpContextBase and/or HttpContextWrapper but again, I'm not sure how to implement them.
Also - I'm not directly testing the getText method. I know it works. I'm testing a class that uses it. Will mocking the HttpContext even help in this situation?
I do realize that this is sort of a hybrid of a unit test / integration test, so if this isn't the best way, I'm all ears... or.. eyes rather.
Edit
For now, I modified my getText method to return the key (name) if the result of HttpContext.GetGlobalResourceObject is null. Then I updated my tests to expect the key instead of the value. It's not ideal, but it works and allows me to continue. If there's a better way, please let me know.
public static class MyStaticClass {
public static string getText(String name)
{
String s = HttpContext.GetGlobalResourceObject("MyResources", name);
return s != null ? s.ToString() : name;
}
}
Original answer with Fakes (see below for dealing with removing static)
So there's one caveat that I completely forgot about until I just tried to do this. I am pretty sure Fakes still requires Enterprise version of VS. I don't know if there's a way to get it to work with NUnit, but when you aren't able to change the code sometimes you have to just deal with it.
Here's an example of Shimming your static method. You don't need to worry about HttpContext (yet) since you aren't using it directly. Instead you can Shim your getText(string) method.
Actual Business Project
namespace FakesExample
{
public class MyStaticClass
{
public static string GetText(string name)
{
throw new NullReferenceException();
}
}
}
Your Unit Test Project
using System;
using Microsoft.QualityTools.Testing.Fakes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FakesExampleTests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
using (ShimsContext.Create())
{
FakesExample.Fakes.ShimMyStaticClass.GetTextString = (s) =>
{
return "Go away null reference";
};
Console.WriteLine(FakesExample.MyStaticClass.GetText("foo"));
}
}
}
}
I actually ran this so I know it works. What happens is that even though GetText will always throw a NullReferenceException when called, our Shim of it returns our own custom message.
You may have to make a Visual Studio Test Project.
In your Unit Test project, right-click your reference and say "Add Fakes". It will generate all of the Shims and Stubs for your assembly.
Process of removing the static
The best solution is to actually work towards removing the static. You've already hit one major reason to not use them.
Here's how I would go about removing the static and removing the dependency on HttpContext
public interface IResourceRepository
{
string Get(string name);
}
public class HttpContextResourceRepository : IResourceRepository
{
public string Get(string name)
{
return HttpContext.GetGlobalResourceObject("MyResources", name).ToString();
}
}
public class MyFormerStaticClass
{
IResourceRepository _resourceRepository;
public MyFormerStaticClass(IResourceRepository resourceRepository)
{
_resourceRepository = resourceRepository;
}
public string GetText(string name)
{
return _resourceRepository.Get(name);
}
}
I would then leverage Dependency Injection to handle the creation of my HttpContextResourceRepository and MyStaticClass (which should probably also be interfaced) in the actual business code.
For the unit test, I would mock the implementation
[TestFixture]
public class UnitTest1
{
[Test]
public void TestMethod1()
{
var repoMock = new Mock<IResourceRepository>();
repoMock.Setup(repository => repository.Get("foo")).Returns("My Resource Value");
var formerStatic = new MyFormerStaticClass(repoMock.Object);
Console.WriteLine(formerStatic.GetText("foo"));
}
}
Going this route, you can create any number of IResourceRepository implementations and swap them whenever you want.

Isolating Service Fabric ServiceContext for unit testing

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).

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());
}

Rhino Mocks, Interfaces and properties

I have a class that has a property that I need to stub. I can't pass it as part of the constructor because the object constructing it does not know the parameters of the constructor.
When running unit tests, I want to be able to have the property be created as a stub.
This is what I have tried, but it does not work:
private DeviceMediator deviceMediator;
private IDeviceControlForm deviceControlForm;
private IDataAccess data;
private ICallMonitor callMonitor;
// Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
// This line works fine
deviceControlForm = MockRepository.GenerateStub<IDeviceControlForm>();
// This line works fine
data = MockRepository.GenerateStub<IDataAccess>();
// This has to be an ICallMonitor. If I try to make it a
// CallMonitor then it fails.
callMonitor = (CallMonitor)
MockRepository.GenerateStub<ICallMonitor>();
// This line does not compile. Because it wants to
// return a CallMonitor not an ICallMonitor.
Expect.Call(new CallMonitor(null)).Return(callMonitor);
// This is the class that has the CallMonitor (called callMonitor).
deviceMediator = new DeviceMediator(deviceControlForm, data);
}
Is there anyway to catch the constructor call to CallMonitor and make it actually be a stub?
In case it is relevant, here is the related code in DeviceMediator:
private IDeviceControlForm form;
private readonly IDataAccess data;
public ICallMonitor CallMonitor { get; set; }
public DeviceMediator(IDeviceControlForm form, IDataAccess data)
{
this.form = form;
this.data = data;
CallMonitor = new CallMonitor(OnIncomingCall);
}
Thanks in advance for any help.
Since the CallMonitor property is writable, you can just overwrite the original value with a mock instance (your DeviceMediator actually implements the Property Injection design pattern).
So you can write a test like this:
[TestMethod]
public void MyTest()
{
var deviceControlForm = MockRepository.GenerateStub<IDeviceControlForm>();
var data = MockRepository.GenerateStub<IDataAccess>();
var mockCallMonitor = MockRepository.GenerateStub<ICallMonitor>();
var deviceMediator = new DeviceMediator(deviceControlForm, data);
deviceMediator.CallMonitor = mockCallMonitor;
// The rest of the test...
}
Firstly you can stub/mock classes directly in RhinoMock so if you want an actual CallMonitor stub rather than ICallMonitor you can, and this will overcome the casting issue in your code. The reason the cast fails is that RhinoMock creates a 'dynamic proxy' object which is not CallMonitor.
Secondly you cannot mock constructor calls, and most importantly there is no way to mock the call to new CallMonitor in the DeviceMediator constructor since there is no way to inject an instance.
The usual way to do what you want would be to change the DeviceMediator constructor to this:
public DeviceMediator(IDeviceControlForm form, IDataAccess data, ICallMonitor callMonitor) { ... }
Then your test can inject a stub/mock instance of this interface into the constructor.
EDIT: If you really can't inject an instance into the constructor then you have a few options:
Create a factory which you can stub:
public class CallMonitorFactory
{
public virtual CallMonitor CreateMonitor(args...) { }
}
public DeviceMediator(IDeviceControlForm form, IDataAccess data, CallMonitorFactory factory)
{
this.form = form;
this.data = data;
CallMonitor = factory.CreateMonitor(OnIncomingCall);
}
Add a protected factory method on DeviceMediator which returns a CallMonitor. You will then have to manually create a sub-class of DeviceMediator in your test so you can return the mock CallMonitor object.
Move the constructor argument for CallMonitor into a method/property that is called in the DeviceMediator constructor.
It appears you're trying to listen for an event of some kind on the CallMonitor, so you could (and should if this is the case) add an event which the DeviceMediator subscribes to. In this case you can use RhinoMock to mock the event raising call like this:
[Test]
public void IncomingCallTest()
{
IEventRaiser callEvent;
CallMonitor monitor = mocks.Stub(args..);
using(mocks.Record())
{
callEvent = monitor.Stub(m => m.IncomingCall += null).IgnoreArguments().GetEventRaiser();
//rest of expectations...
}
using(mocks.Playback())
{
DeviceMediator mediator = new DeviceMediator(form, data, monitor);
callEvent.Raise(sender, args);
}
}
However, as noted above, you cannot mock constructor calls using RhinoMock since this would require some changes to the generated IL (assuming it's even possible).
I do not have too much experience with Rhino in particular, but did you try casting the callMonitor to a CallMonitor in the call to Return?
For example:
Expect.Call(new CallMonitor(null)).Return((CallMonitor)callMonitor);
EDIT:
On second thought, it looks like Return might be a generic method, which means this could be an additional option
Expect.Call(new CallMonitor(null)).Return<CallMonitor>(callMonitor);

Categories