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.
Related
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'm working with the FakeItEasy library to create fakes for my unit tests.
I have a ClassUnderTest on which I want to test the method MethodToTest(Data dataObject). This method is calling a method of an interface which I want to fake:
public interface IFoo
{
void Execute(Action<IDataAccess> action);
}
public class ClassUnderTest
{
private IFoo _foo;
public ClassUnderTest(IFoo foo)
{
_foo = foo;
}
public void MethodToTest(Data dataObject)
{
_foo.Execute(dataAccess => dataAccess.Update(dataObject));
}
}
public interface IDataAccess
{
void Update(Data data);
}
public class Data
{
public int Property { get; set; }
}
In my unit tests I want to check if the test method calls the interface correctly (with the correct property value):
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var foo = A.Fake<IFoo>(x => x.Strict());
A.CallTo(() => foo.Execute(dataAccess => dataAccess.Update(A<Data>.That.Matches(d => d.Property == 20))));
var cut = new ClassUnderTest(foo);
cut.MethodToTest(new Data { Property = 20 });
}
}
But something is configured wrong in this test. I get the exception:
Test method TestProject1.UnitTest1.TestMethod1 threw exception:
FakeItEasy.ExpectationException: Call to non configured method "Execute" of strict fake.
Does somebody have an idea of how I have to configure the CallTo() statement correctly?
The updated example really helps, #rhe1980.
First some notes about the test you supplied:
the A.CallTo method doesn't do anything - it's not setting up behaviour (with a .Invokes or a .Returns or even a .DoesNothing) or verifying that the method has been called (for example with .MustHaveHappened).
Comparing Actions appears to be tough. I did find some advice over at Compare Delegates Action<T>, but if it were me, I'd take a slightly different tack.
Instead of attempting to compare the Action delegate to a reference model, I figured I could emulate this by capturing the action supplied to Execute and then running it on an IDataAccess and see what the action does. Fortunately, we have FakeItEasy to help with that!
I had success with this test:
[TestMethod]
public void TestMethod1()
{
// Arrange
var foo = A.Fake<IFoo>(x => x.Strict());
var fakeDataAccess = A.Fake<IDataAccess>();
A.CallTo(() => foo.Execute(A<Action<IDataAccess>>.Ignored))
.Invokes((Action<IDataAccess> action)=>action(fakeDataAccess));
var cut = new ClassUnderTest(foo);
// Act
cut.MethodToTest(new Data { Property = 20 });
// Assert
A.CallTo(() => fakeDataAccess.Update(A<Data>.That.Matches(d => d.Property == 20)))
.MustHaveHappened();
}
I hope it helps.
If I understood your intentions correctly, you need to use something as follows:
A.CallTo(() => foo.Execute(A<Action<IDataAccess>>.Ignored).MustHaveHappened();
Here is an example where I am testing the line if (true). But although the condition is obviously true, Moq tells me the method was never called.
public class test
{
public virtual void start()
{
if (true)
called();
}
public virtual void called()
{
}
}
[Test]
public void QuickTest()
{
var mock = new Mock<test>();
mock.Object.start();
mock.Verify(t => t.start(), "this works");
mock.Verify(t => t.called(), "crash here: why not called?");
}
How do I test that the method call to called() has happened?
I thought Moq was the solution, but from the comments it looks like it isn't so I've made another example without any reference to Moq:
public class test
{
public bool condition = true;
public test(bool cond)
{
condition = cond;
}
public virtual string start()
{
var str = "somestuff";
if (condition)
str += called();
str += "something more";
return str;
}
public virtual string called()
{
return "something more";
}
}
[Test]
public void ConditionTrue_CallsCalled()
{
var t = new test(true);
t.start();
//syntax? t.HasCalled("called");
Assert.IsTrue(result.Contains("something more"));
}
[Test]
public void ConditionFalse_NoCall()
{
var t = new test(false);
t.start();
//syntax? t.HasNotCalled("called");
// Can't check this way because something more is already being added
Assert.IsFalse(result.Contains("something more"));
}
Is it possible to do this? Is it worthwhile?
Regarding the first piece of code:
mock is a mock object. That means all the methods are overridden and do nothing. So it's entirely normal that calling mock.start() doesn't do anything and called() is never called.
If you want to mock just called() and use the real implementation of start(), you need to do partial mocking.
But I would advise against that, I would even advise against trying to test just this class. You will couple your test code too tightly to your implementation code. Think about doing TDD: ask yourself what feature of your application breaks if that if test is not there. Write a test against that feature, which should fail. Then write the if test to fix the test.
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());
}
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.