Rhino Mocks LastCall syntax help, .NET - c#

I have a problem understanding LastCall() method.
Below is an example:
public interface IDemo
{
string Prop { get; set; }
void VoidNoArgs();
}
[TestMethod]
public void SetupResultUsingOrdered()
{
MockRepository mocks = new MockRepository();
IDemo demo = mocks.StrictMock<IDemo>();
SetupResult.For(demo.Prop).Return("Ayende");
using(mocks.Ordered())
{
demo.VoidNoArgs();
LastCall.On(demo).Repeat.Twice();
}
mocks.ReplayAll();
demo.VoidNoArgs();
for (int i = 0; i < 30; i++)
{
Assert.AreEqual("Ayende",demo.Prop);
}
demo.VoidNoArgs();
mocks.VerifyAll();
}
Am I right in saying:
LastCall.On(demo).Repeat.Twice(); specifies that demo.VoidNoArgs(); is called twice and the last call.
However, there is a code block between demo.VoidNoArgs(). Does it mean that property is not counted when using LastCall method?

Disclaimer: Non-regular Rhino-mocks user.
SetupResult does not seem to be setting an expectation in this case. Since you're using a StrictMock, you need to be explicit in setting expectations on every call made on the mock.
If you want the test to
check on only two calls on VoidNoArgs and not anything else : Comment the SetupResult line.
check seq - VoidNoArgs > Prop.get > VoidNoArgs
.
using (mocks.Ordered())
{
demo.VoidNoArgs();
Expect.On(demo).Call(demo.Prop).Return("Ayende"); // fails unless you use .Repeat.Times(30) or make just one call.
demo.VoidNoArgs();

Related

Use FakeItEasy's A.CallTo() on another method in same object

Using FakeItEasy, how do I check to see if my object's method calls another method on this same object?
The Test:
[TestMethod]
public void EatBanana_CallsWillEat()
{
var banana = new Banana();
var myMonkey = new Monkey();
myMonkey.EatBanana(banana);
//this throws an ArgumentException, because myMonkey is a real instance, not a fake
A.CallTo(() => myMonkey.WillEat(banana)
.MustHaveHappened();
}
The Class:
public class MyMonkey {
private readonly IMonkeyRepo _monkeyRepo;
public MyMonkey(IMonkeyRepo monkeyRepo) {
_monkeyRepo = monkeyRepo;
}
public void EatBanana(Banana banana) {
//make sure the monkey will eat the banana
if (!this.WillEat(banana)) {
return;
}
//do things here
}
public bool WillEat(Banana banana) {
return !banana.IsRotten;
}
}
I'm open to suggestions. If I'm going about this all wrong, please let me know.
Why are you mocking tested object? What exactly are you trying to test? The verification that call to WillEat happened is of little value. What information does it server to consumer? After all, consumer doesn't care how method is implemented. Consumer cares what are the results.
What happens when monkey eats banana that is not rotten? Your test should answer this question:
[TestMethod]
public void EatBanana_CAUSES_WHAT_WhenBananaIsNotRotten()
{
var repo = A.Fake<IMonkeyRepo>();
var monkey = new Monkey(repo);
var freshBanana = new Banana { IsRotten = false };
monkey.EatBanana(freshBanana);
// verifications here depend on what you expect from
// monkey eating fresh banana
}
Note that you can make all sort of verifications to IMonkeyRepo, which is properly faked and injected here.
It's possible to do this. If the WillEat method were virtual - otherwise FakeItEasy won't be able to fake it out.
With that change, you could do this:
[TestMethod]
public void EatBanana_CallsWillEat()
{
var fakeMonkey = A.Fake<MyMonkey>();
fakeMonkey.EatBanana(new Banana());
A.CallTo(()=>fakeMonkey.WillEat(A<Banana>._)).MustHaveHappened();
}
I'm still not convinced it's a good idea (as I ranted in the comments) - I think you'd be better off relying on other observable behaviour, but I'm not familiar with your system. If you think this is the best way to go, the example code should work for you.

LoadTesting, How to get work done in TestInitialize without effecting Avg. Test Time

Some of the tests in my loadtest have two steps involved in order get the data I need, however I want to test the time it take for each component of that process individually so I can easily save it to my load test database, and allow another person to create a report on it. For example I need to test the times of these two methods:
public FooObject[] GetFooList()
public FooObject GetFoo( FooId )
The way you would use these is like so:
FooObject[] results = GetFooList();
FooObject finalResult = GetFoo( results[0].FooId );
I want to know how long GetFooList() and GetFoo() takes to complete, so I thought by doing the prep work for needed for GetFoo() in the TestInitialize method, that it wouldn't effect the test time that was recorded. After some testing with thread.sleep(), I realized that its not the case. Here is my class as it stands now.
[TestClass]
public class MyTestClass
{
public static object f;
public static Random r = new Random();
public TestContext TestContext { get; set; }
[TestInitialize]
public void testInit() {
if( TestContext.TestName == "GetFooTest" ) {
FooObject[] results = GetFooList();
f = results[ r.nextInt( results.Length ) ];
}
}
[TestMethod]
public void GetFooTest()
{
GetFoo( ((FooObject)f).FooId );
}
[TestMethod]
public void GetFooListTest()
{
GetFooList();
}
}
I was wondering if:
1. There was a way for the load test to ignore the TestInitalize component of a test, or
2. if not if there was a suggestion on how I could get around this issue.
I have about 10 or so different pairs of these methods to do ( GetBarList, GetBar, etc...) that's why I store f in a generic object, and eventually let the test initialize have a big switch statement. Any help would be much appreciated. Thanks!
IFAIK, the timings not including the TestInitialize.
Also, you can use with Timer:
this.TestContext.BeginTimer("transaction name");
//the code you want to measure
this.TestContext.EndTimer("transaction name");

Moq for c# training not working on first test in suite

I'm new to c# as well and the Moq framework. I'm using VS 2010 express and NUnit
In my [Setup] function, I have:
this.mockAllianceController = new Mock<AllianceController>();
this.mockAllianceController.Setup(ac => ac.getAllies(this.currentRealm)).Returns(new List<string>());
...
this.testObj = new DiplomacyLogic(this.mockAllianceController.Object);
The first test in the suite gets a null returned, while each test after that gets the empty list. What am I missing?
Update:
Code under test:
public void ApplyRelations() {
List<string> allies = this.AllianceController.getAllies(this.RealmName);
foreach (string ally in allies) {
...
}
}
public virtual List<string> getAllies(string realm) {
...
}
Two test cases:
[Test]
public void aTest() {
this.testObj.ApplyRelations();
}
[Test]
public void bTest() {
this.testObj.ApplyRelations();
}
aTest will throw a NullReferenceException while bTest passes fine. Any help?
It would be helpful if you also show the declaration of getAllies and what this.currentRealm is.
But you probably want to change the line:
this.mockAllianceController.Setup(ac => ac.getAllies(this.currentRealm)).Returns(new List<string>());
into this:
this.mockAllianceController.Setup(ac => ac.getAllies(It.IsAny<string>())).Returns(new List<string>());
Note the It.IsAny<string>() as parameter for getAllies().
If AllianceController is a class and not an interface, you may want to do:
this.mockAllianceController = new Mock<AllianceController>();
this.mockAllianceController.CallBase = True
this means that you create a Mock object that will wrap an existing object and map all method calls to the original object by default (unless an explicit Setup has been called)
(see http://code.google.com/p/moq/wiki/QuickStart#Customizing_Mock_Behavior)
I think your setups is done in the wrong order and this causes the setup not to be valid in the first testrun and then in the second testrun the this.testObj = new DiplomacyLogic(this.mockAllianceController.Object); is already created and the setup is initilazed. This means you should initialize the DiplomacyLogic before the setup to get your desired result.
I also included a teardown code so you get fresh objects for each test, this is good practice so that tests are not dependent on eachother.
try the code below.
[Setup]
public void Setup()
{
this.mockAllianceController = new Mock<AllianceController>();
this.testObj = new DiplomacyLogic(this.mockAllianceController.Object);
this.mockAllianceController.Setup(ac => ac.getAllies(this.currentRealm)).Returns(new List<string>());
}
[TearDown]
public void TearDown()
{
this.mockAllianceController = null;
this.testObj = null;
}
I also think that the setup code should be in the testmethod insteed of setup and that is becasuse of other tests you might write will maby not use the same setup for just that method.

Confused about this unit test!

So basically, I have an abstract class which has a unique, incremental ID - Primitive. When a Primitive (or more precisely, an inheritor of Primitive) is instantiated, the ID is incremented - up to the point where the ID overflows - at which point, I add a message to the exception and rethrow.
OK, that all works fine... but I'm trying to test this functionality and I've never used mocking before. I just need to make enough Primitives for the ID to overflow and assert that it throws at the right time.
It is unreasonable to instantiate 2 billion objects to do this! However I don't see another way.
I don't know if I'm using mocking correctly? (I'm using Moq.)
Here's my test (xUnit):
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
for (; ; )
{
var mock = new Mock<Primitive>();
}
});
}
and:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive()
{
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
I assume I'm doing it wrong - so how do I test this properly?
You don't need mocking for this. You use mocking when two classes work together and you want to replace one class with a mock (fake) one so you only have to test the other one. This is not the case in your example.
There is however a way you could use mocks, and that fixes your issue with the 2bln instances. If you separate the ID generation from the Primitive class and use a generator, you can mock the generator. An example:
I've changed Primitive to use a provided generator. In this case it's set to a static variable, and there are better ways, but as an example:
public abstract class Primitive
{
internal static IPrimitiveIDGenerator Generator;
protected Primitive()
{
Id = Generator.GetNext();
}
internal int Id { get; private set; }
}
public interface IPrimitiveIDGenerator
{
int GetNext();
}
public class PrimitiveIDGenerator : IPrimitiveIDGenerator
{
private int? _previousId;
public int GetNext()
{
try
{
_previousId = checked(++_previousId) ?? 0;
return _previousId.Value;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
Then, your test case becomes:
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
var generator = new PrimitiveIDGenerator();
for (; ; )
{
generator.GetNext();
}
});
}
This will run a lot faster and now you're only testing whether the ID generator works.
Now, when you e.g. want to test that creating a new primitive actually asks for the ID, you could try the following:
public void Does_primitive_ask_for_an_ID()
{
var generator = new Mock<IPrimitiveIDGenerator>();
// Set the expectations on the mock so that it checks that
// GetNext is called. How depends on what mock framework you're using.
Primitive.Generator = generator;
new ChildOfPrimitive();
}
Now you have separated the different concerns and can test them separately.
The point of the mock is to simulate an external resource. It's not what you want, you want to test your object, no mock needed in this szenario. Just instantiate the 2 billion objects if you like to, it doesn't hurt since the GC will throw away the old instances (but may take a while to complete).
Id' actually add another constructor which accepts a strarting value for the identity counter, so that you can actually start close to int.MaxValue and therefore don't need to instatiate as many objects.
Also, just from readin the source I can tell that your object will fail the test. ;-)
You have two problems baked into this question:
How to unit test an abstract class, that you can't instantiate.
How to efficiently unit test functionality that requires two billion instances to be created and destroyed.
I think the solutions are pretty simple, even though you'll have to re-think the structure of your object slightly.
For the first problem, the solution is as simple as adding a fake that inherits Primitive, but adds no functionality, to your test project. You can then instantiate your fake class instead, and you'll still be testing the functionality of Primitive.
public class Fake : Primitive { }
// and in your test...
Assert.Throws(typeof(OverflowException), delegate() { var f = new Fake(int.MaxValue); });
For the second problem, I'd add a constructor that takes an int for the previous ID, and use constructor chaining to "not need it" in your actual code. (But how to you get to know of the previous id otherwise? Can't you set that to int.MaxValue-1 in the setup of your test?) Think of it as dependecy injection, but you're not injecting anything complex; you're just injecting a simple int. It could be something along these lines:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive() : Primitive([some way you get your previous id now...])
protected Primitive(int previousId)
{
_previousId = previousId;
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
All has been said in the other answers. I just want to show you an alternative, maybe this is somehow interesting for you.
If you made the _previousId field of your Primitive class internal (and included the respective InternalsVisibleTo attribute, of course), then your test could be as simple as this with the Typemock Isolator tool:
[Fact(DisplayName = "Test Primitive count limit"), Isolated]
public void TestPrimitiveCountLimit()
{
Primitive._previousId = int.MaxValue;
Assert.Throws<OverflowException>(() =>
Isolate.Fake.Instance<Primitive>(Members.CallOriginal, ConstructorWillBe.Called));
}
Sure, Typemock comes with some license costs, but it definitely makes life much easier and saves you a lot of time, if you have to write large amounts of test code - especially on systems which are not easily tested or are even impossible to test with a free mocking framework.
Thomas

Unit Test Throwing "System.NullReferenceException", using Moq and Nunit

I am newbie to moq and unit testing. So, I don't understand it thoroughly. pardon me if question is stupid. please help me understand the following scenario.
Following is my simple test
[Test]
public void TryMoq() {
var mock = new Mock<IDummyInterface>();
var dummy = new DummyClass(mock.Object);
mock.VerifySet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo"));
}
and the code that I m trying to test
public class DummyClass
{
public DummyClass(IDummyInterface i) {
i.Model = new DummyModel() ;
i.Model.MyProperty = "foo";
}
}
public class DummyModel
{
public string MyProperty { get; set; }
}
public interface IDummyInterface {
DummyModel Model { get; set; }
}
now at line "i.Model.MyProperty = "foo";" "System.NullReferenceException" is being thrown.
Why, I think the reason in since I m using Moq.
strange thing is that if i change the constructor of the "DummyClass". Like this
public DummyClass(IDummyInterface i)
{
i.Model = new DummyModel() { MyProperty ="foo"};
//i.Model.MyProperty = "foo";
}
Test Passes . In the second case even if I try changing the value of "foo" to "bar". Test Fails.(This is good though).
I just want to understand whats going on. and how am I suppose to moq and verify child properties.
The difference between the two cases is that when you write
i.Model = new DummyModel() { MyProperty ="foo"};
you are essentially writing
var dummyModel = new DummyModel() { MyProperty ="foo"};
i.Model = dummyModel;
that is, you pass to your interface an object where the property is already set to "Foo". Your tests asserts that "someone will try to set the property on the Mock to an object of type DummyModel, where the property MyProperty is set to "Foo"", which is exactly what is happening.
The first case fails because after the following line executes, i.Model is null.
i.Model = new DummyModel();
Getting or setting a property on a Mock directly will NOT set the property, it will merely do nothing or return a null, unless you specify what you want it to do. So in that case what happens is that in the 2nd line of your constructor, i.Model is null, which causes the null exception on i.Model.MyProperty.
The mock does not remember the value of the property unless you tell it to:
i.Model = new DummyModel();
will cause the mock to remember that you set it to that object. However it will still return null if you access the property. If you want it to behave like an automatic property, use:
mock.SetupAllProperties();
Now
i.Model.MyProperty = "foo";
will not fail anymore. With mocks you always need to specify all behavior explicitly.
Read more on: http://code.google.com/p/moq/wiki/QuickStart
you can also do something like:
var mock = new Mock<IDummyInterface>();
mock.SetupSet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo")).Verifiable();
var dummy = new DummyClass(mock.Object);
mock.Verify();
Moq's default implementation of m.Model is to return null, so you're going to need to give Dummy() something more than a default mock.

Categories