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.
Related
I'm using MoQ in C# to do some Unit tests/BDD tests, and I've often the need of generating the same object twice(because it will be potentially used in dictionary). Or something 99% the same but just with a different ID.
Is there a way to "clone" the Mock definition? Or to generate two objects with the same definition?
You should create a helper method that constructs that takes in some parameters to construct the Mock object.
[Test]
public void MyTest()
{
Mock<ITestObject> myMock = CreateObject(1);
ITestObject obj = myMock.Object;
}
private Mock<ITestObject> CreateObject(int id)
{
Mock<ITestObject> mock = new Mock<ITestObject>();
mock.SetupGet(o => o.ID).Returns(id);
return mock;
}
private interface ITestObject
{
int ID { get; set; }
}
If you just need a collection of data to unit test with, you may consider something like AutoFixture as well. It can work with Moq in the case of classes you want to mock. You teach AutoFixture how to create YourClass, and you can even set rules like "my IDs should be strings with capital letters and no more than X amount of them."
Then you'd just use autofixture.
var fixture = new Fixture();
var tetsClasses = fixture.CreateMany<TestClass>();
This is really just to give you an idea. You can do quite a but more with it, and it plays really well with Moq.
An alternative is to use a data builder pattern to create your data. So you could start with something simple and just keep adding onto it as you find new edge cases on how you need to build the data. Just build a fluent API on it and build the data however you want.
internal class TestClassBuilder<T> : where T : TestClass
{
int Id {get; set;}
public T WithId(int id)
{
this.Id = id;
return this;
}
public virtual T Build()
{
return new T()
{
if(this.Id)
Id = this.Id; // if you chose to set it, then assign it
else
Id = GetRandomId() // you can figure a solution here
}
}
}
Then call it like:
var stubOne = TestClassBuilder.WithId(1).Build();
You can extend it to build a list if you want.
I like fluent APIs on data builders, because you can start to tell your story with the methods you create, and it keeps your Arrange section neat and tidy.
Example:
var UnderAgeCustomer = new CustomerBuilder
.UnderAge
.WithFakeId
.InACrowd
.LooksYoung
.Build()
You could even add on
public static implicit operator T(TestClassBuilder<T> builder)
{
return builder.Build();
}
And you wouldn't need to use the .Build() part all the time (I think build adds unnecessary noise). Just don't try assigning that to a var, it won't work.
TestClass MockTwo = TestClassBuilder.WithId(2);
I would say you could also use a fixture pattern to track of all this ... but between that and the databuilder, you may as well use AutoFixture and Moq as I suggested :)
I'm currently attempting to implement the humble object design pattern. The only resource I can find regarding this is from the xunit testing web site. Unfortunately, I don't really understand it despite reading it several times. Is there perhaps another name this pattern goes by?
Here is what I have thus far.
public interface IHumbleExchangeWebService
{
GetItemResult BindToItems(IEnumerable<string> itemIds);
SyncFolderItemsResult Sync();
void Subscribe();
}
public class ExchangeWebServiceAdapter
{
private readonly IHumbleExchangeWebService _humbleExchangeWebService;
public ExchangeWebServiceAdapter(
IHumbleExchangeWebService humbleExchangeWebService)
{
_humbleExchangeWebService = humbleExchangeWebService;
Start();
}
private void Start()
{
SyncFolderItemsResult syncFolderItemsResults;
while(true)
{
syncFolderItemsResults = _humbleExchangeWebService.Sync();
if(syncFolderItemsResults != null)
break;
}
ProcessSyncResults(syncFolderItemsResults);
LastSyncDateTime = Time.Now;
_humbleExchangeWebService.Subscribe();
}
private void ProcessSyncResults(SyncFolderItemsResult syncFolderItemsResults)
{
if (syncFolderItemsResults.Count <= 0) return;
var missedItemIds = syncFolderItemsResults.ItemChange
.ToList()
.Select(x => x.ExchangeItem.ItemId);
_humbleExchangeWebService.BindToItems(missedItemIds);
}
public DateTime LastSyncDateTime { get; private set; }
}
And as for the testing:
[TestFixture]
public class Tests
{
private Mock<IHumbleExchangeWebService> _humbleExchangeWebServiceMock;
[SetUp]
public void SetUp()
{
_humbleExchangeWebServiceMock = new Mock<IHumbleExchangeWebService>();
}
[Test]
public void OnInitialiseWillSyncBeforeSubscribing()
{
var callOrder = 0;
_humbleExchangeWebServiceMock
.Setup(x => x.Sync())
.Returns(() => new SyncFolderItemsResult(0, false, String.Empty, GetExchangeItemChangeList()))
.Callback(() => Assert.That(callOrder++, Is.EqualTo(0)));
_humbleExchangeWebServiceMock
.Setup(x => x.Subscribe())
.Callback(() => Assert.That(callOrder++, Is.EqualTo(1)));
var service = GetConstructedService();
_humbleExchangeWebServiceMock.Verify(x => x.Sync(), Times.Once());
_humbleExchangeWebServiceMock.Verify(x => x.Subscribe(), Times.Once());
}
[Test]
public void WhenSyncingIsCompleteWillProcessMissingItem()
{
_humbleExchangeWebServiceMock
.Setup(x => x.Sync())
.Returns(new SyncFolderItemsResult(1, false, It.IsAny<string>(), GetExchangeItemChangeList()));
var service = GetConstructedService();
_humbleExchangeWebServiceMock.Verify(x => x.BindToItems(It.IsAny<IEnumerable<string>>()));
}
[Test]
public void BindingItemsWillProcess()
{
_humbleExchangeWebServiceMock
.Setup(x => x.Sync())
.Returns(new SyncFolderItemsResult(1, false, It.IsAny<string>(), GetExchangeItemChangeList()));
var service = GetConstructedService();
_humbleExchangeWebServiceMock
.Verify(x => x.BindToItems(new []{"AAA", "BBB", "CCC", "DDD"}), Times.Once());
_humbleExchangeWebServiceMock.VerifyAll();
}
private ExchangeWebServiceAdapter GetConstructedService()
{
return new ExchangeWebServiceAdapter(_humbleExchangeWebServiceMock.Object);
}
private IEnumerable<ExchangeItemChange> GetExchangeItemChangeList()
{
yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("AAA"));
yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("BBB"));
yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("CCC"));
yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("DDD"));
}
}
Essentially, I'm simply wondering if I'm on the right track of making the humble object dumb. What I mean is that is it the proper way to extract all conditions that I can easily unit test into a wrapper class (e.g. ExchangeWebServiceAdapter).
A good rule of thumb when trying to implement the humble object pattern is to look at the object you just created and ask yourself how you're going to test all the logic inside it. If you have a general idea of what you're going to do within 10 seconds and it doesn't cause you to groan out loud, you're probably fine. If it takes you any longer than that or if it causes you pain to think about it, you've probably made a mistake somewhere.
As far as understanding of the humble pattern, you can think of it like a car assembly line; the thing that makes those massive lines work is the fact that everything is interchangeable. Engines only Go, heaters only Heat, etc. The simplest way to keep it straight in your mind is to name your classes such that they are a concrete object, and then get rid of anything that doesn't fall under what that object should do. In your specific example, you've named your class an 'adapter'. Okay, so what is it adapting FROM and TO? What two incompatible things is it making compatible? I'd guess part of your confusion is that your class is misnamed or too broad at this point in time. As your understanding grows so will your vocabulary and you might find it's perfectly fine at that point. If you're just learning the pattern, it will inhibit your understanding to jump straight to programmer jargon; a lot of these words we use have poorly defined meanings.
To put it more concretely, if a Starter needs to get other information or kick other resources to finish Starting, that's fine; it's just that those other resources should be clearly named, abstracted out to other classes, and tested separately.
You've done a decent job of making the objects as you've presented them trivial, but obviously you'll need to worry about the implementation of your interface being dumb enough as well, when you get to that point.
Hopefully this helps; the humble object pattern is both distinct and very similar to the ideal of loose coupling that you will hear people talk about all the time. The humble object pattern is simply a specific prescribed way of achieving loose coupling with a bunch of objects that traditionally resist it.
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();
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
I'm new to mocking/testing and wanting to know what level should you go to when testing. For example in my code I have the following object:
public class RuleViolation
{
public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }
public RuleViolation( string errorMessage )
{
ErrorMessage = errorMessage;
}
public RuleViolation( string errorMessage, string propertyName )
{
ErrorMessage = errorMessage;
PropertyName = propertyName;
}
}
This is a relatively simple object. So my question is:
Does it need a unit test?
If it does what do I test and how?
Thanks
it doesn't contain any logic => nothing to test
I would say probably not. The only thing that you would probably want to verify if it is extremely important are the access modifiers:
public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }
If it is really really important that code outside the class cannot modify them that might be the only thing I would try and verify.
Here is how you can get the accessors in a property:
class Program
{
static void Main(string[] args)
{
var property = typeof(Test).GetProperty("Accessor");
var methods = property.GetAccessors();
}
}
public class Test
{
public string Accessor
{
get;
private set;
}
}
With the property.GetAccessors();
You can see if the setter is there. If it is, then the setter is public. (There is also properties IsPrivate and IsPublic you can use to verify the other Accessors as well).
If it were my code and my object I would have tests for it, no matter how simple or complicated the class is, period. Even if the class seems unlikely to break, tests are where, IMO, you document your assumptions, design decisions, and proper usage.
By doing so, you not only validate that what you have works as intended, but you have the opportunity to think through typical scenarios (what happens if the ctor params are null or empty or have white space at the end? Why is the PropertyName optional in an immutable class?).
And IF (when?) requirements change you have a solid starting point for addressing that. And IF this trivial class somehow doesn't interact nicely with all of the other classes, you may have a test to catch that before your customers do.
It's just the right way to engineer your code.
HTH,
Berryl
You could unit test this object, but it's so simple as to not require it. The test would be something like (NUnit example)
[Test]
public void TestRuleViolationConstructorWithErrorMessageParameterSetsErrorMessageProperty() {
// Arrange
var errorMessage = "An error message";
// Act
var ruleViolation = new RuleViolation(errorMessage);
// Assert
Assert.AreEqual(errorMessage, ruleViolation.ErrorMessage);
}
There's little value to writing tests like these, however, as you are testing that the .NET framework's properties work correctly. Generally you can trust Microsoft to have got this right :-)
Regarding mocking, this is useful when your class under test has a dependency, perhaps on another class in your own application, or on a type from a framework. Mocking frameworks allow you call methods and properties on the dependecy without going to the trouble of building the dependency concretely in code, and instead allow you to inject defined values for properties, return values for methods, etc. Moq is an excellent framework, and a test for a basic class with dependency would look something like this:
[Test]
public void TestCalculateReturnsBasicRateTaxForMiddleIncome() {
// Arrange
// TaxPolicy is a dependency that we need to manipulate.
var policy = new Mock<TaxPolicy>();
bar.Setup(x => x.BasicRate.Returns(0.22d));
var taxCalculator = new TaxCalculator();
// Act
// Calculate takes a TaxPolicy and an annual income.
var result = taxCalculator.Calculate(policy.Object, 25000);
// Assert
// Basic Rate tax is 22%, which is 5500 of 25000.
Assert.AreEqual(5500, result);
}
TaxPolicy would be unit tested in its own fixture to verify that it behaves correctly. Here, we want to test that the TaxCalculator works correctly, and so we mock the TaxPolicy object to make our tests simpler; in so doing, we can specify the behaviour of just the bits of TaxPolicy in which we're interested. Without it, we would need to create hand-rolled mocks/stubs/fakes, or create real instances of TaxPolicy to pass around.
There's waaaaay more to Moq than this, however; check out the quick-start tutorial to see more of what it can do.
Even if simple, there's logic in your constructors. I would test that:
RuleViolation ruleViolation = new RuleViolation("This is the error message");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.IsEmpty(ruleViolation.PropertyName);
RuleViolation ruleViolation = new RuleViolation("This is the error message", "ThisIsMyProperty");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.AreEqual("ThisIsMyProperty", ruleViolation.PropertyName);