How to unit testing a method which creates a task - c#

How should the following method be unit tested?
/// <summary>
/// Entry point for GUI thread.
/// </summary>
public void VerifyDataTypesAsync()
{
Task verificationTask = Task.Factory.StartNew(() =>
{
VerifyDataManagerAsync();
});
}
is it only possible to test via integration testing or is it possible to test that a task was created?
Thanks for your help

You can create a Factory for creating this task and use it through seams. You can use property seam - it is when you set the instance of your factory to a property of an under test class or you can use constructor seam by giving the factory through a constructor. Then you can mock this factory and set it through one of two seams and check does your VerifyDataTypesAsync method call the method of creating your task.
class YourClass
{
public YourClass(ITaskFactory factory)
{}
public void VerifyDataTypesAsync()
{
Task verificationTask = factory.Create(); // you can pass an instance of a delegate as parameter if you need.
}
}
class TasksFactory : IFactory
{
public Task Create()
{
}
}
Then in your test you can create a mock object of IFactory and pass it to the constructor of your class then set mock rules for mock to check if the method Create was called.
If we are talking about NUnit and RhinoMocks it can be looked about this:
var mockRepository = new MockRepository();
var mockObject = mockRepository.CreateMock<IFactory>();
var yourClass = new YourClass(mockObject);
Expect.Call(mockObject.Create);
mockRepository.ReplayAll();
mockObject.VerifyDataTypesAsync()
mockRepository.VerifyAll(); // throw Exception if your VerifyDataTypesAsync method doesn't call Create method of IFactory mock
roughly speaking like this... but it is just one way...

You could wrap the creation of the task in your own Task factory class and verify that it has been used correctly by mocking it in the unit test. For example, create a class like this:
class MyTaskFactory
{
public virtual void CreateTask(Action a)
{
Task.Factory.StartNew(a);
}
}
You supply your objects that need to create tasks with one of these factory objects. In a unit test, you supply a mocked version instead of the actual factory, and see if the CreateTask method has been called.
For more information on mocking, have a look at RhinoMocks or Moq.

Related

Can I use MOQ to mock future instances?

I am new to unit testing and trying to figure out a bit more about MOQ.
Is there an API that allows me to mock future instances of some type?
I mean,
Let's say I am mocking a class. Inside that class I use the new operator to create a new instance of an object.
I want to mock all future instances of the same type of that object that will be created within that class in the future, is there such API?
I tried to look into MOQ documentation but there is no such example. Help anyone?
Don't use new, use dependency injection and a factory. Then you can make your class create mocks:
internal class SubjectUnderTest
{
public SubjectUnderTest( IProductFactory factory )
{
_factory = factory;
}
public void DoStuff()
{
var product = _factory.CreateProduct(); // this creates a mocked product (where you new'ed something before)
product.DoSomeThing(); // this calls into the mock product
}
private readonly IProductFactory _factory;
}
A test would then look like this
var mockFactory = new Mock<IProductFactory>();
mockFactory.Setup( x => x.CreateProduct() ).Returns( () =>
{
var mockProduct = new Mock<IProduct>();
// TODO setup product mock here
return mockProduct.Object;
} );
var instance = new SubjectUnderTest( mockFactory.Object );
instance.DoStuff(); // <- uses the factory mock defined above to create a mocked product and calls into the mocked product

How do I setup MOQ to Set property Objects and verify the method [duplicate]

It is my understanding that I can test that a method call will occur if I call a higher level method, i.e.:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
I want to test that if I call SomeMethod() then I expect that SomeOtherMethod() will be called.
Am I right in thinking this sort of test is available in a mocking framework?
You can see if a method in something you have mocked has been called by using Verify, e.g.:
static void Main(string[] args)
{
Mock<ITest> mock = new Mock<ITest>();
ClassBeingTested testedClass = new ClassBeingTested();
testedClass.WorkMethod(mock.Object);
mock.Verify(m => m.MethodToCheckIfCalled());
}
class ClassBeingTested
{
public void WorkMethod(ITest test)
{
//test.MethodToCheckIfCalled();
}
}
public interface ITest
{
void MethodToCheckIfCalled();
}
If the line is left commented it will throw a MockException when you call Verify. If it is uncommented it will pass.
No, mock testing assumes you are using certain testable design patterns, one of which is injection. In your case you would be testing SomeClass.SomeMethod and SomeOtherMethod must be implemented in another entity which needs to be interfaced.
Your Someclass constructor would look like New(ISomeOtherClass). Then you would mock the ISomeOtherClass and set expectation on its SomeOtherMethod to be called and verify the expectation.
Even though I agree that the #Paul's answer is the recommended way to go I just want to add one alternative way which is provided by moq off the self.
Since SomeClass is abstract it is indeed mockable, but public void SomeMehod() isn't. The point is to find the way to mock and somehow invoke that method and then using CallBase propagate the call to the SomeOtherMethod(). It might sound as a hack but it is simple in essence. It could be used in the case if the proposed refactoring is not possible.
// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
public virtual void DummyMethod() => base.SomeMethod();
}
Then you could setup DummyMethod() to propagate the call by setting CallBase flag.
//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();
//Act
mock.Object.SomeMethod();
//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

Moq CallBase on mock of interface

Let's assume we have the following setup:
public interface IBase
{
void Foo();
}
public class Base : IBase
{
public virtual void Foo()
{
Console.WriteLine("Called Base.Foo()");
}
}
public interface IChild : IBase
{
void Bar();
}
public class Child : Base, IChild
{
public virtual void Bar()
{
Console.WriteLine("Called Child.Bar()");
}
}
When mocking the Child object everything works fine:
var child = new Mock<Child> { CallBase = true };
child.Object.Bar();
child.Object.Foo();
Output is:
Called Child.Bar()
Called Base.Foo()
But when mocking the IChild interface nothing is printed to the console:
var child = new Mock<IChild> { CallBase = true };
child.Object.Bar();
child.Object.Foo();
Let's assume I can't mock the Child object because there is no parameterless constructor (dependency injection).
I know that I could just do the following:
child.Setup(c => c.Bar()).Callback(() =>
{
// Copy paste bar-method body
});
child.Setup(c => c.Foo()).Callback(() =>
{
// Copy paste foo-method body
});
But that would be very ugly.
Is there a clean solution using Mock<IChild>?
As long as you are mocking the interface, you have no access or information about the real classes which explains why you don't get any output (but I guess you understood that).
Unfortunately if you choose to mock an interface (which by definition have no behavior), the only way to make things happen is to Setup the method the way you did.
Another "dirty" way would be to use method extension to your child and base class if the content of the method is only using public attributes and method.
public static class ChildExtension
{
public static void Bar(this Child child)
{
Console.WriteLine("Called Child.Bar()");
}
}
You are going to the wrong direction
Mock exists to help in unit testing. For example if you want to test the method Save() of a class which uses a wrapper over a DbContext like the following:
interface IRepository
{
void PersistData(object dataToBeSaved);
}
class DataSaver
{
private IRepository _repository;//this object's method PersistData makes a call to a database
public DataSaver(IRepository repository)
{
_repository = repository;
}
public void Save(object dataToBeSaved)
{
_repository.PersistData(dataToBeSaved);
}
}
In this case, in order to test the method Save of the DataSaver you will do a call to it in a unit test, but the problem you will face when doing this is that the method will actually try to save the data using the repository objet. Unless you send a fake repository your unit test will save data every time you run it, and this is not what a unit test should be doing. It should not run a method from a concrete IRepository object, but it should still call it's method.
What you could do in this case to avoid saving of an object is to make another class which implements IRepository only for testing:
class DummyRepository : IRepository
{
public object DataJustSaved { get; set; }
public void PersistData(object dataToBeSaved)
{
DataJustSaved = dataToBeSaved;
}
}
Now in your unit test you will do something like this:
var dummyRepository = new DummyRepository();
var dataSaver = new DataSaver(dummyRepository);
var savedObject = new Object();
var expectedObject = savedObject;
dataSaver.Save(savedObject);//test the save method
var actualObject = dummyRepository.DataJustSaved;
Assert.AreEqual(expectedObject, actualObject);//verify that the data was passed to the PersistData method
Here the Mock helps
It would be quite difficult to make a fake class for each unit test, that is what alternative mock offers:
var dummyRepository = new Mock<IRepository>();
var dataSaver = new DataSaver(dummyRepository.Object);
var savedObject = new Object();
dataSaver.Verify(x => x.PersistData(savedObject), Times.Once());// just make sure the method PersistData was invoked with the expected data and only once.
The reason Mock exists is to make pretty smart dummies for you, to write unit tests without a great impact but which can reveal bugs, and keep the code doing what only it's supposed to do.
In your case, if you really want to call the actual method of the concrete object:
child.Setup(c => c.Bar()).Callback(() =>
{
Console.WriteLine("Called Child.Bar()");
});
Then it means that you should not even try to use the mock to reproduce the exact same implementation of the object you mock. What would be the use of the mock if it is doing the same thing as the actual object?
In this case you should remove the mock and create a concrete Child object, as you do not want to simulate the behavior of a child, you are trying to achieve it using a mock which removes the functionality of the mock itself.
The simple answer is to use the concrete object in the unit test:
var child = new Child();
child.Bar();
child.Foo();

Mocks to verify interaction

Typically when I need to mock out a class for testing, I'll use a library such as Rhino Mocks. Here I have a class called MyService that expects a IEmailSender.
public class MyService
{
private readonly IEmailSender sender;
public MyService(IEmailSender sender)
{
this.sender = sender;
}
public void Start()
{
this.sender.SendEmail();
}
}
If I needed to test the interaction between these two objects, my test would look something like this:
[TestMethod]
public void Start_Test_Using_Rhino_Mocks()
{
IEmailSender emailSender = MockRepository.GenerateMock<IEmailSender>();
MyService service = new MyService(emailSender);
service.Start();
emailSender.AssertWasCalled
(
x => x.SendEmail(),
c => c.Repeat.Once()
);
}
In the test above, I'm using Rhino Mocks to generate the mock and assert that the SendEmail() method was called once.
But what if I could not use Rhino Mocks and had to create manual mocks?
public class MockEmailSender : IEmailSender
{
public void SendEmail()
{
}
}
[TestMethod]
public void Start_Test_Using_Manual_Mocks()
{
MockEmailSender emailSender = new MockEmailSender();
MyService service = new MyService(emailSender);
service.Start();
// How do I test the interaction?
}
With the mock that I created manually, how would I verify that the SendEmail() method was called? I could put my assertions in the SendEmail() method of the mock, but that would make the test hard to understand since I don't immediately see what's going on when I look at the test.
A very simple solution would have your manual mock just be a stateholder, with counters for the calls to each method. But it's fragile ...
public class MockEmailSender : IEmailSender
{
public int SendCount = 0;
public void SendMail(...)
{
SendCount++;
}
// ... other IEmailSender methods ...
}
Then just query SendCount after making your method call, and making sure that it's == 1.
Remember, Rhino Mocks is creating this dynamically for you -- if you do it manually you have to react to interface changes before compile time, by hand.
I think that you have no other option than setting a flag in "SendEmail()", and checking that flag from the test throgh a new method of MockEmailSender like "sendMailWasInvoked()" or something like this (which is in fact a kind of "verify").
You can extend this to count the number of invokations, parameters...
well i would advise against creating any manual Mocks (because if you add new method to interface, it gets broken).
if you really have to do it, when expose some counter/bool in your MockEmailSender and you can Assert it later on.
Assert.IsTrue(emailSender.IsCalled)

Rhino Mocks Partial Mock

I am trying to test the logic from some existing classes. It is not possible to re-factor the classes at present as they are very complex and in production.
What I want to do is create a mock object and test a method that internally calls another method that is very hard to mock.
So I want to just set a behaviour for the secondary method call.
But when I setup the behaviour for the method, the code of the method is invoked and fails.
Am I missing something or is this just not possible to test without re-factoring the class?
I have tried all the different mock types (Strick,Stub,Dynamic,Partial ect.) but they all end up calling the method when I try to set up the behaviour.
using System;
using MbUnit.Framework;
using Rhino.Mocks;
namespace MMBusinessObjects.Tests
{
[TestFixture]
public class PartialMockExampleFixture
{
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
//setup mocks
MockRepository mocks = new MockRepository();
var mockTestClass = mocks.StrictMock<TestClass>();
//record beahviour *** actualy call into the real method stub ***
Expect.Call(mockTestClass.MethodToMock(param)).Return(true);
//never get to here
mocks.ReplayAll();
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
}
public class TestClass
{
public bool MethodToMock(string param)
{
//some logic that is very hard to mock
throw new NotImplementedException();
}
public bool MethodIWantToTest(string param)
{
//this method calls the
if( MethodToMock(param) )
{
//some logic i want to test
}
return true;
}
}
}
}
MethodToMock is not virtual and therefore can't be mocked. What you want to do is possible with a partial mock (I've done it in cases similar to yours), but the method you want to mock out must be either part of an interface implementation or be marked virtual. Otherwise, you can't mock it with Rhino.Mocks.
I recommend not mocking methods in the class under test, but your situation may be unique in that you can't refactor the class to make it easier to test at present. You might try explicitly making a delegate to prevent the method from being invoked when setting up the call.
Expect.Call( delegate { mockTestClass.MethodToMock(param) } ).Return(true);
Or, switch to using the AAA syntax, omitting the deprecated constructs.
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
var mockTestClass = MockRepository.GenerateMock<TestClass>();
mockTestClass.Expect( m => m.MethodToMock(param) ).Return( true );
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
mockTestClass.VerifyAllExpectations();
}

Categories

Resources