Scratching my head how to do this.
Suppose I had a concrete class Foo with 2 virtual methods, Execute() and GetFile(). Execute() will call GetFile. I want to make sure that when it does, GetFile() will throw a couple of different exceptions that Foo is supposed to handle gracefully in a testable manner.
For my unit tests, I am envisioning instantiating a DynamicProxy<Foo> from castle project where I intercept the GetFile() to throw the exception, and then invoke the DynamicProxy object's Execute() method, and test the results, but I can't see how to do this.
Is this possible/ practical? If so, what would the creation of the dynamic proxy object look like?
You don't need to handcode your own proxy because most the mocking frameworks support your scenario.
Here is an example using Moq (Moq will create a dynamic proxy internally for you):
public class SomeException : Exception { }
public class Foo
{
public virtual int Execute()
{
try
{
GetFiles();
}
catch (SomeException)
{
return 1;
}
return 0;
}
public virtual void GetFiles()
{
//...
}
}
[Test]
public void FooTest()
{
var fooUnderTest = new Mock<Foo>();
fooUnderTest.CallBase = true;
fooUnderTest.Setup(f => f.GetFiles()).Throws(new SomeException());
var result = fooUnderTest.Object.Execute();
Assert.AreEqual(1, result);
}
You just need to take care to set Callbase = true which will:
Invoke base class implementation if no expectation overrides the
member (a.k.a. "Partial Mocks" in Rhino Mocks): default is false.
Related
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.)
Let's say, I have methods A, B, C and D.
public bool A (int foo)
{
bool result = false;
if (foo > 0)
result = B();
else result = C();
D(foo);
return result;
}
I want to write a unit test for A, with calling B or C, but want to skip the D call (because it is a method using external services). Is it possible to skip the D call using some attributes? Or mock the D, substituting it with some fake service?
You need to make the class that has method A() depend upon the external service(s) used by method D(). You can use any of the DI patterns to do this, although constructor injection is probably the best starting point.
Once you're in this situation, the external service(s) D() depends upon can be faked and injected into the class. Testing is now under your control via the fake(s)'s behaviour.
Something like:
class Thing
{
private IExternalService _externalService;
public Thing(IExternalService externalService)
{
_externalService = externalService;
}
public void A() { ... }
public void D(string foo)
{
_externalService.DoSomeStuff();
}
}
Then:
[Fact]
public void TestThisOut()
{
var fakeExternalService = new MockFramework.CreateMock();
fakeExternalService
.ShouldDoSomethingWhen(s => s.DoSomeStuff())
.IsCalled();
var testThing = new Thing(fakeExternalService);
testThing.A();
Assert.That(testThing, Did.Some.Thing());
}
This highlights the importance of designing your code so it is unit testable. Dependency injection is very useful in this regard. you can then mock dependencies when unit testing. You may have a communications layer that you could access via an interface ICommunications for example. Your class would then take a reference to an ICommunications object in its contructor:
public class TestableClass
{
private ICommunications _comms;
public TestableClass(ICommunications comms)
{
_comms = comms;
}
public bool FunctionToTest()
{
//do something testable
_comms.SomeFunction();//mocked object in unit tests
//do something else testable
}
}
Then just create a mock version of comms and pass that in during testing. You can also add code to your mocked class to emulate certain test conditions - eg for a comms layer receiving some invalid data.
You need to mock method D. I wrote an example, using Typemock Isolator, take a look:
class Methods
{
public bool A(int foo)
{
bool result = false;
if (foo > 0)
result = B();
else
result = C();
D(foo);
return result;
}
public void D(int foo) {throw new NotImplementedException();}
public bool C() { return false;}
public bool B() { return true;}
}
And the test:
[TestMethod, Isolated]
public void TestIgnoreD()
{
//Arrange
Methods methods = new Methods();
Isolate.WhenCalled(() => methods.D(0)).IgnoreCall();
//Act
bool result = methods.A(1);
//Assert
Assert.IsTrue(result);
}
I put them all in one class just because I don't know what's going on in your code. Anyway, Isolator rather flexible as it allows to mock almost everything from almost everywhere.
I am using some COM library in my C# which is bound to particular hardware and doesn't work without it. On development/testing computer I don't have that hardware. The method which is using library looks like this:
using HWSysManagerLib;
bool ProcessBias(HWSysManager systemManager, string hwPath)
{
int handle = systemManager.OpenConfiguration(hwPath);
...
// some magic goes here
// return result
}
The question is, can I mock HWSysManager for test method and how? There are few methods only in HWSysManager and it wouldn't be problem to simulate their functionality for test. A tiny example would be great on how to mock it, if it's possible at all.
You can use the adapter pattern here.
Create an interface named IHWSysManager
public interface IHWSysManager
{
int OpenConfiguration(string hwPath);
}
The real implementation class just delegates the work to the library:
public class HWSysManagerImpl : IHWSysManager
{
private HWSysManager _hwSysManager; //Initialize from constructor
public int OpenConfiguration(string hwPath)
{
return _hwSysManager.openConfiguration(hwPath);
}
}
Use the interface in your code like this:
bool ProcessBias(IHWSysManager systemManager, string hwPath)
{
int handle = systemManager.OpenConfiguration(hwPath);
...
// some magic goes here
// return result
}
Now you can mock your IHWSysManager interface with mock frameworks or you can create a stub class yourself.
You can use Typemock Isolator for faking HWSysManager.
For your example, you can do the following:
var fakeManager = Isolate.Fake.Instance<HWSysManager>();
Isolate.WhenCalled(() => fakeManager.OpenConfiguration("")).WillReturn(0);
And then, you can pass this faked manager to ProcessBias(IHWSysManager systemManager, string hwPath) as an argument.
As you said, you can simulate a few methods from IHWSysManager. So, me advice is to set up the behavior of this manager's methods using DoInstead():
Isolate.WhenCalled(() => fakeManager.OpenConfiguration("")).DoInstead(
context =>
{
//Your simulation
});
You can look here for more information. I think, it can be really useful for you.
I suppose you should create HWSysManager(or some other name) class to your Mock cases, add there some wanted methods and then mock them. For example:
class HWSysManager
{
public virtual int ExampleReturnIntMethod(int a)
{
var someInt = 0;
return someInt;
}
and then setup:
public void TestMethod()
{
Mock<HWSysManager> hwSysManager = new Mock<HWSysManager>();
hwSysManager.Setup(x => x.ExampleReturnInMethod(It.IsAny<int> ())).Returns(10); //if parameter is any of int, return 10 in this case
}
Then to use your Mocked object just use the 'object' property:
var hwSysInstance = hwSysManager.Object;
var result = hwSysInstance.ExampleReturnInMethod(2); //result will be 10 in this case - as we have mocked
In case above your methods/properties have to be virtual.
You can use interfaces also, in your case:
public interface HwsysManager
{
int OpenConfiguration(string hwPath);
}
public void TestMethod()
{
Mock<HwsysManager> hwsysManager = new Mock<HwsysManager>();
hwsysManager.Setup(x => x.OpenConfiguration(It.IsAny<string>())).Returns(10);
}
All features of this Mock library are described here:
https://github.com/Moq/moq4/wiki/Quickstart
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'd like to be able to test a class initialises correctly using Moq:
class ClassToTest
{
public ClassToTest()
{
Method1(#"C:\myfile.dat")
}
public virtual void Method1(string filename)
{
// mock this method
File.Create(filename);
}
}
I thought I'd be able to use the CallBase property to create a testable version of the class, then use .Setup() to ensure Method1() does not execute any code.
However, creating the Mock<ClassToTest>() doesn't call the constructor, and if it did it'd be too late to do the Setup()!
If this is impossible, what is the best way round the problem whilst ensuring that the constructor behaves correctly?
EDIT: To make it clearer, I've added a parameter to Method1() to take a filename and added some behaviour. The test I'd like to write would be a working version of the following:
[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
var mockClass = new Mock<ClassToTest>() { CallBase = true };
mockClass.Setup(x => x.Method1(It.IsAny<string>());
mockClass.Verify(x => x.Method1(#"C:\myfile.dat"));
}
Way down inside of Moq.Mock (actually inside the CastleProxyFactory that Moq uses)
mockClass.Object
will call the constructor by way of Activator.CreateInstance()
So your test would look something like
[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
Mock<ClassToTest> mockClass = new Mock<ClassToTest>();
mockClass.Setup(x => x.Method1(It.IsAny<string>());
var o = mockClass.Object;
mockClass.Verify(x => x.Method1(#"C:\myfile.dat"));
}