Is that possible in RhinoMocks to create mock object without it constructor invocation?
public class A
{
public A()
{
throw new InvalidOperationException("Mock me!");
}
}
[Test]
public void TestCtors()
{
MockRepository mocks = new MockRepository();
A a = (A)mocks.StrictMock(typeof(A));
Assert.IsTrue(true, "Should be eligible");
}
I don't think there is a way around this if you are mocking a concrete class. If you could mock in interface instead that would obviously not call a constructor. Would it be possible to re-work your code so that A implements and interface which you can mock?
Related
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);
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();
Does the methods in mocked objects work ?
For example if I have an object with method name Method1 and I mock the object :
var mockobject= Mock<myobject>();
Does the next call to method work :
mockobject.Method1()
?
It is a question to clarify about the mock objects.
If you're mocking a concrete class or abstract class with method implementations. For virtual methods you have two options.
Create a Setup to fake the method call
mockobject.Setup(x => x.Method1()).Returns(true);
Set CallBase = true on the mock to invoke the concrete behavior of the Method1 method.
mockobject.CallBase = true;
Usage:
public class MyClass
{
public virtual int MyMethod()
{
return 5;
}
}
[Test]
public void ShouldGiveMeZero()
{
var mockMyClass = new Mock<MyClass>();
// returns default(int)
Assert.AreEqual(0, mockMyClass.Object.MyMethod());
}
[Test]
public void ShouldGiveMeFive()
{
var mockMyClass = new Mock<MyClass>();
mockMyClass.CallBase = true;
// calls concrete implementation
Assert.AreEqual(5, mockMyClass.Object.MyMethod());
}
[Test]
public void ShouldGiveMeSix()
{
var mockMyClass = new Mock<MyClass>();
mockMyClass.Setup(x => x.MyMethod()).Returns(6);
// calls Setup
Assert.AreEqual(6, mockMyClass.Object.MyMethod());
}
First, note that your example will never compile:
mockobject.Method1()
Method1 doesn't live on the mock object itself--it lives in the underlying mocked object instance:
mockobject.Object.Method1();
The behavior of that call depends on what MockBehavior you're using (Strict or Loose). It also depends on if the method you're calling is marked virtual or not.
If Method1 is non-virtual, the implementation for the actual type will be used, since Mock cannot mock non-virtual methods.
For example, if MyObject is defined like this:
public class MyObject
{
public int Method1()
{
return 1;
}
}
mockObject.Object.Method1() will return 1 since Mock is unable to provide any other implementation for the method.
Now, if Method1 is declared virtual:
public virtual int Method1()
{
return 1;
}
The MockBehavior comes into play. The default is MockBehavior.Loose, which means that methods not defined using the .Setup method will return default(T) where T is the return type of the method. So the following:
var mockObject = new Mock<MyObject>(MockBehavior.Default);
int result = mockObject.Object.Method1();
Will always return 0 unless you use .Setup to make it return otherwise. You can also specify CallBase = true on the Mock<MyObject> instance and the base implementation will be invoked for methods that aren't defined using .Setup.
If you're using MockBehavior.Strict, unimplemented methods will throw an exception:
var mockObject = new Mock<MyObject>(MockBehavior.Strict);
int result = mockObject.Object.Method1(); // Always throws an exception
If you look at the quickstart guide there are simple examples to get you going, e.g.
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
Note the call to Setup to make the mock/fake actually do something.
In this situation you have created the default stub for Method1. If you were to create this by hand you would have code similar to:
public class MyObject {
public virtual void Method1() {
throw new NotImplementedException();
}
}
Your stub would be:
public class Stub : MyObject {
public override void Method1() {
}
}
So now instead of getting a NotImplementedException you have an instance of MyObject that will allow you to call Method1 regardless of its original implementation.
Note my usage of virtual. Without the usage of virtual there is nothing for Moq to override.
This is actually one of my favorite usages of mocking. Many people go overboard with interfaces for everything "for mocking". The most baseline scenarios only require methods to be virtual. In general I mark nearly every public method I create as virtual. If a public method cannot be virtual, it is likely a violation of the Open Closed Principle.
I've been using Ninject for dependency injection and inversion of control, and I have been using Moq for testing purposes quite successfully; however, I recently came into a position in which I needed to start using the factory extension of Ninject.
I have code along the lines of:
interface IBarFactory
{
Bar CreateBar();
}
class Bar : IBar
{
...
}
class BarModule
{
public override void Load()
{
Bind<IBarFactory>().ToFactory();
}
}
class Tests
{
[Fact]
public void TestMethod()
{
var bar = new Mock<IBar>();
bar.Setup(b => b.DoSomething())
.Verifiable();
var barFactory = new Mock<IBarFactory>();
cryptoKeyFactoryMock.Setup(f => f.CreateBar())
.Returns(bar.Object)
.Verifiable();
var someOtherClass = new SomeOtherClass(barFactory.Object);
}
}
When attempting to force the IBarFactory mock to return an IBar mocked object, I get an error due to the fact that the CreateBar() method expects a Bar typed object rather than an IBar typed one.
Has anyone had more success using Moq with Ninject Factory?
I don't think the issue is Ninject specifically, but just that you seem to be declaring an Interface solely for testing. Is there a reason that the BarFactory shouldn't return IBar?
Moq can mock classes, not just interfaces. You can set up a Mock<Bar> instance for the mocked BarFactory call to return. The caveat is that any methods/properties you want to assert on the Mocked Bar instance must be declared as virtual. So in your example, if you declare DoSomething() as virtual then you can set up a mock of type Bar with your declaration instead of IBar.
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.