Question about Rhino Mock (RhinoAutoMocker) - rhino-mocks

I have a question about Rhino Mock.
I am trying to put restriction on what methods could be called from the method that is under test.
Lets say I have a method that I am writing the Unit Test against like this:
public void MyMethod()
{
var test = _Repository.Get(2);
_Services.DoSomething(test);
}
what I do right now is something like this :
[Test]
public void TestMethod()
{
var mock1 = CreateMock<IRepository>();
var mock2 = CreateMock<IServices)();
mock1.Expect(x => x.Get(1).IgnoreArguments().Return(new Poo()).Repeat.Once();
mock2.Expect(x => x.DoSomething(new Something()).IgnoreArguments().Repeat.Once();
ClassUnderTest.MyMethod();
mock1.VerifyAllExpectations();
mock2.VerityAllExpectations();
}
this is fine but what I want is to prevent somebody to change the method like this:
public void MyMethod()
{
var test = _Repository.Get(2);
var test = _Repository.Save(test);
_Services.DoSomething(test);
}
As you can see Save method on Repository is called, so this is dangerous obviously because if somebody by mistake add that line there we will be in trouble.
How can I restrict someond from doing that ? Thanks.

There are a few options:
Strict Mocks
Strict mocks throw an exception if they are called in a way that doesn't match an expectation. You can create strict mocks like this:
var mocks = new MockRepository();
var fooStrictMock = mocks.StrictMock<IFoo>();
.Repeat.Never()
If you are only interested in preventing calls to just one particular method, you can use the .Repeat.Never() quantifier on an expectation like this:
mock1.Expect(x => x.Save(null)).IgnoreArguments().Repeat.Never();
AssertWasNotCalled
You can call AssertWasNotCalled at the end of your test like this:
var repositoryStub = MockRepository.GenerateStub<IRepository>();
repositoryStub.Stub(x => x.Get(2)).Return(...);
var underTest = new UnderTest(repositoryStub);
underTest.DoSomething();
repositoryStub.AssertWasNotCalled(x => x.Save(Arg<Thing>.Is.Anything));

Related

How to mock and expect a method with Action delegate as one of the parameter with Moq

I am using Automapper in my .net core application to map. I have a method like below
public MyEntity TransformtoToEntity(MyDTO dto)
{
var entity = _mapper.Map<MyEntity, MyDTO>(dto, opts => opts.Items["isUpdate"] = "N");
return entity;
}
My test method looks like
[Fact]
public void Returns_Data_After_Mapping()
{
// Arrange
var mockEntityData = new MyEntity
{
Id = 1,
Name = "John"
};
var mockDto = new MyDTO
{
Id = 1,
Name = "John"
};
var mappingOperationMock = new Mock<IMappingOperationOptions<MyDTO, MyEntity>>(MockBehavior.Strict);
mappingOperationMock.Setup(x => x.Items).Returns(new Dictionary<string, object>() { { "isUpdate", "N" }});
_mapper.Setup(x => x.Map(It.IsAny<MyDTO>(),
It.IsAny<Action<IMappingOperationOptions<MyDTO, MyEntity>>>()))
.Returns(mockEntityData);
// Act
var result = _myMapper.TransformDtoToEntity(mockDto);
// Assert
Assert.NotNull(result);
_mapper.VerifyAll();
mappingOperationMock.VerifyAll();
}
Here how can I verify that IMappingOperationOptions parameters are correctly passed. Or is there any better way to do a unit test here. Basically I am stuck with how to effectively unit test methods who are having Action delegate parameters. I referred the thread Testing a method accepting a delegate with Moq, but could not find anything I can assert or verify inside the callback.
If you would like to test what is happening in your action delegate you can use the callback from moq.
Something like
Action<IMappingOperationOptions<MyEntity, MyDto>> mappingOperationAction = default;
_mapper.setup(x.Map(myDto, It.IsAny<Action<IMappingOperationOptions<MyEntity,MyDto>>>())
.callBack<MyDto, Action<IMappingOperationOptions<MyEntity,MyDto>>>( (callbackMyDto, callbackMappingOperationAction) => mappingOperationAction = callbackMappingOperationAction);
var mappingOperation = new MappingOperationOptions<MyEntity, MyDto>(_ => default);
mappingOperationAction.Invoke(mappingOperation);
Assert.AreEqual("N", mappingOperation.Items["isUpdate"])

Clear call history of a mock

question: is it possible to clear the call history of a mock (or stub)?
( and with call history I don't mean the expected / recorded behaviour.)
The details:
I currently want am writing the following code with tests according the AAA syntax using NUnit and Rhino mocks.
public abstract class MockA
{
private bool _firstTime = true;
public void DoSomething()
{
if (_firstTime)
{
OnFirstDoSomething();
_firstTime = false;
}
}
public abstract void OnFirstDoSomething();
}
[TestFixture]
public class MockATest
{
[Test]
public void DoSomethingShouldSkipInitializationForSequentialCalls()
{
// Arrange
var mockA = MockRepository.GeneratePartialMock<MockA>();
mockA.Expect(x => x.OnFirstDoSomething()).Repeat.Any();
mockA.DoSomething(); // -> OnFirstDoSomething() is called
// here I want clear the call history of mockA
//Act
mockA.DoSomething(); // -> OnFirstDoSomething should NOT be called
mockA.DoSomething(); // -> OnFirstDoSomething should NOT be called
//assert
mockA.AssertWasNotCalled(x => x.OnFirstDoSomething());
}
}
For the readability I always try to focus the calls in the Assert section on the changes that occur within the Act section.
However, the arrange section in this test, contains a (required) action that influence the call history of mockA.
As a result the assert fails.
I known I could catch a 'change' in the call history using the construction below, but it makes the expected behaviour of this test less readable.
{
...
mockA.AssertWasCalled(x => x.OnFirstDoSomething(), opt => opt.Repeat.Once());
//Act
mockA.DoSomething();
//Assert
mockA.AssertWasCalled(x => x.OnFirstDoSomething(), opt => opt.Repeat.Once());
}
My question: is it possible to clear the call history of a mock (not recorded Expectations)?
You don't need to clear call history. Use Stub method instead of Expect in Arrange section:
[Test]
public void DoSomethingShouldSkipInitializationForSequentialCalls()
{
// Arrange
var mockA = MockRepository.GeneratePartialMock<MockA>();
// this is what you have to change
mockA.Stub(x => x.OnFirstDoSomething()).Repeat.Any();
mockA.DoSomething(); // -> OnFirstDoSomething() is called
// here I want clear the call history of mockA
//Act
mockA.DoSomething();
mockA.DoSomething();
//assert
mockA.AssertWasNotCalled(x => x.OnFirstDoSomething());
}

composing MEF parts in C# like a simple Funq container

In Funq and probably most other IoC containers I can simply do this to configure a type:
container.Register<ISomeThing>(c => new SomeThing());
How could I quickly extend MEF (or use existing MEF functionality) to do the same without using attributes.
Here is how I thought I could do it:
var container = new CompositionContainer();
var batch = new CompositionBatch();
batch.AddExport<ISomeThing>(() => new SomeThing());
batch.AddExportedValue(batch);
container.Compose(batch);
With this extension method for CompositionBatch:
public static ComposablePart AddExport<TKey>(this CompositionBatch batch, Func<object> func)
{
var typeString = typeof(TKey).ToString();
return batch.AddExport(
new Export(
new ExportDefinition(
typeString,
new Dictionary<string, object>() { { "ExportTypeIdentity", typeString } }),
func));
}
If I later do:
var a = container.GetExport<ISomeThing>().Value;
var b = container.GetExport<ISomeThing>().Value;
Both instance are the same. How can I force (configure) them to be different instances?
If this is not the way to go, how would I do this in MEF?
I would imagine the key is to add the delegate to the container, e.g.:
container.AddExportedValue<Func<ISomething>>(() => new Something());
That way you can grab the delegate and execute it:
var factory = container.GetExport<Func<ISomething>>();
ISomething something = factory();
Of course, MEF (Silverlight) does provide a native ExportFactory<T> (and ExportFactory<T,TMetadata> type that supports the creation of new instances for each call to import. You can add support for this by downloading Glen Block's ExportFactory for .NET 4.0 (Desktop) library.
If you don't want to use attributes, you can use this trick (based on Mark Seemann's blogpost).
First, create a generic class like this:
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MefAdapter<T> where T : new()
{
private readonly T export;
public MefAdapter()
{
this.export = new T();
}
[Export]
public virtual T Export
{
get { return this.export; }
}
}
Now you can register any class you want in the container, like this:
var registeredTypesCatalog = new TypeCatalog(
typeof(MefAdapter<Foo>),
typeof(MefAdapter<Bar>),
...);
var container = new CompositionContainer(catalog);
Alternatively, you could implement your own export provider derived from ExportProvider, which allows you to pretty much duplicate Funq's way of working:
var provider = new FunqyExportProvider();
provider.Register<IFoo>(context => new Foo());
var container = new CompositionContainer(provider);
Both instance are the same. How can I force (configure) them to be different instances?
Simply mark the SomeThing class like this:
[Export(typeof(ISomeThing)]
[PartCreationPolicy(CreationPolicy.NonShared]
public class SomeThing : ISomeThing
{
...
}
And then you will get different instances wherever you import ISomeThing.
Alternatively, you can also set a required creation policy on an import:
[Export(typeof(IFoo))]
public class Foo : IFoo
{
[Import(typeof(ISomeThing),
RequiredCreationPolicy = CreationPolicy.NonShared)]
public ISomething SomeThing { private get; set; }
}
In Glen Block's Skydrive directory linked to in Matthew Abbott's answer I found something that seems simple and lightweight: A FuncCatalog. Download it here: FuncCatalogExtension.
Using the few little classes from that project I could now do this:
var funcCatalog = new FuncCatalog();
funcCatalog.AddPart<ISomeThing>(ep => new SomeThing());
var container = new CompositionContainer(funcCatalog);
var batch = new CompositionBatch();
batch.AddExportedObject<ExportProvider>(container);
container.Compose(batch);
var a = container.GetExportedObject<ISomeThing>();
var b = container.GetExportedObject<ISomeThing>();

Rhino moq Property.value constraint

My following straight forward test doesn't pass (Though I feel it should). Either I am missing something or is not clear of Property.value constraint. please help me in understanding concept of property.value constraint.
public interface ISomeInterface
{
void SomeMethod(string x, string y);
}
public class SomeClassTest
{
[Test]
public void SomeMethodTest()
{
MockRepository mocks = new MockRepository();
ISomeInterface mockservice = mocks.StrictMock<ISomeInterface>();
using (mocks.Record())
{
mockservice.SomeMethod("xValue", "yValue");
LastCall.Constraints(Property.Value("x", "xValue"),
Property.Value("y", "yValue"));
}
mockservice.SomeMethod("xValue", "yValue");
mocks.Verify(mockservice);
}
}
Exception raised:
Rhino.Mocks.Exceptions.ExpectationViolationException : ISomeInterface.SomeMethod("xValue", "yValue"); Expected #0, Actual #1.
ISomeInterface.SomeMethod(property 'x' equal to xValue, property 'y' equal to yValue); Expected #1, Actual #0.
I would recommend you the following syntax (AAA syntax):
// arrange
var mockservice = MockRepository.GenerateMock<ISomeInterface>();
// act
mockservice.SomeMethod("xValue", "yValue");
// assert
mockservice.AssertWasCalled(
x => x.SomeMethod("xValue", "yValue")
);
This sample class illustrates the options for asserting methods were called with appropriate properties:
public class UsesThing
{
private IMyThing _thing;
public UsesThing(IMyThing thing)
{
_thing = thing;
}
public void DoTheThing(int myparm)
{
_thing.DoWork(myparm, Helper.GetParmString(myparm));
}
public void DoAnotherThing(int myparm)
{
AnotherThing thing2 = new AnotherThing();
thing2.MyProperty = myparm + 2;
_thing.DoMoreWork(thing2)
}
}
Using simple values for assertions may work for methods like the DoTheThing method which uses value types:
[Test]
public void TestDoTheThing()
{
IMyThing thing = MockRepository.GenerateMock<IMyThing>();
UsesThing user = new UsesThing(thing);
user.DoTheThing(1);
thing.AssertWasCalled(t => t.DoWork(1, "one");
}
However, if you need to create an object in your method and pass it as a parameter like in the DoAnotherThing method, this approach will not work since you will not have a reference to the object. You have to check the property values of the unknown object, like this:
[Test]
public void TestDoAnotherThing()
{
IMyThing thing = MockRepository.GenerateMock<IMyThing>();
UsesThing user = new UsesThing(thing);
user.DoAnotherThing(1);
thing.AssertWasCalled(t => t.DoMoreWork(null), t => t.IgnoreArguments().Constraints(Property.Value("MyProperty", 3))));
}
The new Rhino syntax would look like the following, but I am crashing VS 2008 when I use it:
thing.AssertWasCalled(t => t.DoMoreWork(Arg<AnotherThing>.Matches(Property.Value("MyProperty", 3))));

Testing In A Try Catch With Moq Compared To Rhino Mocks

I've just been working on some tests using Moq but ran into trouble trying to test a method I wanted to call twice through a try catch block. The principle is that the first call throws an exception, then in the catch I correct the problem and call the method again.
I managed to do it with Rhino Mocks as below but being new to both frameworks I wondered if anyone could tell me if the same can be achieved using Moq.
// C.U.T
public class Mockee
{
bool theCatLives = true;
public Mockee() { }
public virtual void SetFalse()
{
theCatLives = false;
}
}
[Test]
public void TestTryCatch(){
var mr = new MockRepository();
var mock = mr.StrictMock<Mockee>();
mr.Record();
Expect.Call(mock.SetFalse).Throw(new Exception());
Expect.Call(mock.SetFalse);
mr.ReplayAll();
try
{
mock.SetFalse();
}
catch
{
mock.SetFalse();
}
mock.VerifyAllExpectations();
}
This isn't particularly easy to do with Moq, as it has no concept of ordered expectations. You can, however, use the Callback method and throw exceptions from there, like this:
var actions = new Queue<Action>(new Action[]
{
() => { throw new Exception(); },
() => { }
});
var mock = new Mock<Mockee>();
mock.Setup(m => m.SetFalse()).Callback(() => actions.Dequeue()()).Verifiable();
try
{
mock.Object.SetFalse();
}
catch
{
mock.Object.SetFalse();
}
mock.Verify();
However, one caveat is that this version only checks whether the SetFalse method was called at all.
If you want to verify that it was called twice, you can change the last statement to this:
mock.Verify(m => m.SetFalse(), Times.Exactly(2));
However, this slightly violates the DRY principle because you would be stating the same Setup twice, but you could get around that by first declaring and defining a variable of type Expression<Action<Mockee>> and use it for both the Setup and the Verify methods...