I am trying to use the yield command to update some methods but I am running into an issue that I don't understand. There is some logic in this method (checking for type of null), if that is the case then I write to a log and yield break. Which does exactly what I want, however in my unit test it is saying that the log function was never called. I am ok with not logging in this situation but I want to know why I can't or if I am doing something wrong.
Here is the code:
public IEnumerable<Ixxx> GetTypes(Type type)
{
if (type == null)
{
log.WriteRecord("log error", "LogName", true);
yield break;
}
lock (blockingObject)
{
foreach (Ixxx item in aDictionary.Values)
{
if (item.Type.Name == type.Name)
{
yield return item;
}
}
}
}
The unit test that is failing is claiming log.WriteRecord was never called. Here is that unit test:
[TestMethod]
public void TestMethod()
{
// Arrange
mockLog.Setup(a => a.WriteRecord(It.IsAny<string>(), It.IsAny<string>(), true)).Returns(true);
// Act
sut.GetTypes(null);
// Assert
mockLog.Verify(a => a.WriteRecord(It.IsAny<string>(), It.IsAny<string>(), true), Times.Once());
}
When I was making a local copy (List) this test passed however now that I am using yield it appears I can not make any function calls within this method? Thanks for any help!
The line "sut.GetTypes(null)" just returns an IEnumerable that you are throwing away. Since you never iterate over the enumerable, none of the code in GetTypes ever executes.
Try this instead:
foreach (var x in sut.GetTypes(null)) {}
Related
I have a service that
Makes a call to each registered class that implements a specific interface (IUnorderedService)
Then makes a final call to another service (IFinalService)
I want to write a test that asserts that my service makes a call to each IUnorderedService in no specific order, and then makes a call to the IFinalService. Using FakeItEasy, is there any way to do this?
My implementation looks like this (much simplified):
public class MyService
{
private readonly IFinalService finalService;
private readonly IEnumerable<IUnorderedService> unorderedServices;
public MyService(
IFinalService finalService,
IEnumerable<IUnorderedService> unorderedServices)
{
this.finalService = finalService;
this.unorderedServices = unorderedServices;
}
public void Execute()
{
foreach (var unorderedService in this.unorderedServices)
{
unorderedService.Execute();
}
this.finalService.Execute();
}
}
And my test method would look something like this
public void ShouldCallUnorderedService_BeforeCallingFinalService()
{
// Arrange
...
// Act
myService.Execute();
// Assert
foreach (var unorderedService in unorderedServices)
{
A.CallTo(() => unorderedService.Execute()).MustHaveHappenedOnceExactly();
}
// Should be asserted that this call occurs after all of the above calls have occurred.
A.CallTo(() => finalService.Execute()).MustHaveHappenedOnceExactly();
}
I have played around with the A.CallTo().Then() syntax which works great for most purposes, but I don't see a way assert occurrence of multiple unordered calls prior to an ordered call.
There's nothing directly built into FakeItEasy for this scenario. One option would be to intercept the calls as they are made. Then you could verify the order was as you wanted. The call-intercepting feature is (I believe) infrequently used, so this might be less understandable, but could be worth pursuing.
Then I thought about leveraging the "callback" or Invokes facility on a Fake to record whether a fake call was supposed to be final or not, then verify the setting at the end of the test:
[Fact]
public void ShouldCallUnorderedService_BeforeCallingFinalService()
{
var lastKindOfService = "none";
var unorderedServices = new [] {
A.Fake<IUnorderedService>(),
A.Fake<IUnorderedService>(),
A.Fake<IUnorderedService>(),
};
foreach (var unorderedService in unorderedServices)
{
A.CallTo(() => unorderedService.Execute()).Invokes(() => lastKindOfService = "unordered");
}
var finalService = A.Fake<IFinalService>();
A.CallTo(() => finalService.Execute()).Invokes(() => lastKindOfService = "final");
var service = new MyService(finalService, unorderedServices);
service.Execute();
foreach (var unorderedService in unorderedServices)
{
A.CallTo(() => unorderedService.Execute()).MustHaveHappenedOnceExactly();
}
A.CallTo(() => finalService.Execute()).MustHaveHappenedOnceExactly();
lastKindOfService.Should().Be("final");
}
Of course this could be prettied up with a helper method or enums for the state. And if there's any asynchrony, you might want to serialize the updates.
You can put the A.CallTo().Then() into your foreach
foreach (var unorderedService in unorderedServices)
{
A.CallTo(() => unorderedService.Execute()).MustHaveHappenedOnceExactly()
.Then(A.CallTo(() => finalService.Execute()).MustHaveHappenedOnceExactly()
}
So you are checking that each call to the unordered service happened before the call to the final service. Unfortunately this is not a bulk check, but I think the end result will still prove code correctness
I need to mock a while loop to run just once however my setup makes it run infinite times as I think it returns true always.
My Set up:
var loginName = "12345";
cacheRepository.Setup(m => m.AddString(string.Format("{0}_{1}", Resources.ResetCodeCacheKey, randomCode), loginName)).Returns(true);
While loop in method:
while (_cacheRepository.AddString(string.Format("{0}_{1}", Resources.ResetCodeCacheKey, code), userLoginName))
{
//.........
}
Add String implementation:
public virtual bool AddString(string key, string value)
{
if (!ExistsKey(key))
{
Cache.AddString(key, value);
return true;
}
return false;
}
How can I set up my method to return true just once? A code snippet will be helpful.Thanks for looking into this.
Use SetupSequence to setup the mocked member to return the desired results.
For example say you have the following interface
public interface IInterface {
bool AddString(string key, string value);
}
The setup would look like
var cacheRepository = new Mock<IInterface>();
cacheRepository
.SetupSequence(m => m.AddString(It.IsAny<string>(), It.IsAny<string>()))
.Returns(true)
.Returns(false);
When the mocked member is called the first time is will return true and then false the second time.
Reference Moq Quickstart to get a better understanding of how to use the mocking framework.
Setting up a member to return different values / throw exceptions on sequential calls:
var mock = new Mock<IFoo>();
mock.SetupSequence(f => f.GetCount())
.Returns(3) // will be returned on 1st invocation
.Returns(2) // will be returned on 2nd invocation
.Returns(1) // will be returned on 3rd invocation
.Returns(0) // will be returned on 4th invocation
.Throws(new InvalidOperationException()); // will be thrown on 5th invocation
In a method returning IEnumerable<>, I'm opening and looping over a resource (e.g. a database row reader). Once the loop finished, the resource is closed again.
However, it may happen that the caller decides not to finish the enumeration. This leaves the resource open.
Example:
IEnumerable<Foo> Bar ()
{
using (var r = OpenResource()) {
while (r.Read ()) {
yield return r;
}
}
}
// OK - this closes the resource again
foreach (var foo in Bar()) {
Console.WriteLine (foo);
}
// Not OK - resource stays open!
Console.WriteLine (Bar().First());
How would I solve this? Can I easily cancel an enumeration, i.e. tell it to skip over the rest of the loop, or dispose it (putting the cleanup code in Dispose)?
I considered returning a Func<Result, bool> so the user can have it return false if he's done with iterating. Similarly, some kind of cancel token could be used, too. But both approaches seem cumbersome to me.
Normally it is the IEnumerator<> that implements the IDisposable, and if you look at the definition of IEnumerator<> you'll see that:
public interface IEnumerator<out T> : IDisposable, IEnumerator
The foreach statement correctly Dispose() the IEnumerator<> that receives from the IEnumerable<>, so that:
IEnumerable<SomeClass> res = SomeQuery();
foreach (SomeClass sc in res)
{
if (something)
break;
}
upon exiting the foreach in any way (the break, an exception, naturally finishing res), the Dispose() of the IEnumerator<> should be called. See https://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx for an example of how the foreach is implemented (a try... finally... with a Dispose() inside the finally)
Note that the C# will produce "correct" code for using used inside a yield function. See for example here: http://goo.gl/Igzmiz
public IEnumerable<Foo> Bar()
{
using (var r = OpenResource())
{
while (r.Read ())
{
yield return new Foo();
}
}
}
is converted to something that
void IDisposable.Dispose()
{
int num = this.<>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
this.<>m__Finally1();
}
}
}
The Dispose() method of IEnumerator<> will call a m__Finally1 method that will (IDisposable)this.<r>5__1.Dispose(); (where 5__1 is the r returned from OpenResource()). The m__Finally is even called if the code simply "exits" the while (r.Read ()):
if (!this.<r>5__1.Read())
{
this.<>m__Finally1();
and/or if there is an exception.
catch
{
this.System.IDisposable.Dispose();
I am using Moq to verify if a method is being called in my unittest. In this specific case I want to test if the method under test logs an Error through log4net. The problem is, this can be done by either calling log.Error or log.ErrorFormat. Either is fine.
How can I verify this though? I only know how to verify that they have both been called.
var logMock = new Mock<ILog>();
var myClass = new MyClass(logMock.Object);
myClass.MyMethod();
logMock.Verify(log => log.Error(It.IsAny<object>()));
logMock.Verify(log => log.ErrorFormat(It.IsAny<string>(), It.IsAny<object>()));
Now that I think of it, they both have a bunch of overloads, I don't mind if any of the overloads are called either (I'm starting to doubt this is a good test).
Thanks in advance.
EDIT: I just thought of something nasty:
try
{
logMock.Verify(log => log.Error(It.IsAny<object>()));
}
catch (Moq.MockException ex)
{
logMock.Verify(log => log.ErrorFormat(It.IsAny<string>(), It.IsAny<object>()));
}
Maybe I can wrap this in some kind of extension method... e.g. VerifyAny.
You could register a callback for each valid error method that sets a flag:
// Arrange
bool errorFlag = false;
logMock
.Setup(l => l.Error(It.IsAny<object>()))
.Callback((object o) => errorFlag = true);
/* repeat setup for each logMock method */
// Act
myClass.MyMethod();
// Assert
Assert.IsTrue(errorFlag);
Of course, this will still be tedious if you have many overloads to cover.
EDIT: And for fun, here's an extension method for Mock<T>.VerifyAny:
public static class MockExtensions
{
public static void VerifyAny<T>(this Mock<T> mock, params Expression<Action<T>>[] expressions)
where T: class
{
List<MockException> exceptions = new List<MockException>();
bool success = false;
foreach (var expression in expressions)
{
try
{
mock.Verify(expression);
success = true;
break;
}
catch (MockException ex)
{
exceptions.Add(ex);
}
}
if (!success)
{
throw new AggregateException("None of the specified methods were invoked.", exceptions);
}
}
}
Usage:
[TestMethod]
public void FooTest()
{
Mock<IFoo> fooMock = new Mock<IFoo>();
fooMock.Object.Bar1();
fooMock.VerifyAny(
f => f.Bar1(),
f => f.Bar2());
}
if you are specifically testing that a specific error was logged, why not have 2 tests, one that ensure that log.Error is called and one that ensure that log.ErrorFormat is called, I am assuming that you can control which one is called based on the input.
if you still wanna verify one or the other, you can just use this approach, it does exactly what you need:
Verify that either one method or the other was invoked in a unit test
Is it acceptable to do asserts in your callbacks if you later verify that the methods were called? Is this the preferred way of making sure my mock is getting the expected parameters passed to it, or should I set a local variable in my callback and do the asserts on that instance?
I have a situation where I have some logic in a Presenter class that derives values based on inputs and passes them to a Creator class. To test the logic in the Presenter class I want to verify that the proper derived values are observed when the Creator is called. I came up with the example below that works, but I'm not sure if I like this approach:
[TestFixture]
public class WidgetCreatorPresenterTester
{
[Test]
public void Properly_Generates_DerivedName()
{
var widgetCreator = new Mock<IWidgetCreator>();
widgetCreator.Setup(a => a.Create(It.IsAny<Widget>()))
.Callback((Widget widget) =>
Assert.AreEqual("Derived.Name", widget.DerivedName));
var presenter = new WidgetCreatorPresenter(widgetCreator.Object);
presenter.Save("Name");
widgetCreator.Verify(a => a.Create(It.IsAny<Widget>()), Times.Once());
}
}
I'm concerned because without the Verify call at the end, there is no guarantee that the assert in the callback would be invoked. Another approach would be to set a local variable in the callback:
[Test]
public void Properly_Generates_DerivedName()
{
var widgetCreator = new Mock<IWidgetCreator>();
Widget localWidget = null;
widgetCreator.Setup(a => a.Create(It.IsAny<Widget>()))
.Callback((Widget widget) => localWidget = widget);
var presenter = new WidgetCreatorPresenter(widgetCreator.Object);
presenter.Save("Name");
widgetCreator.Verify(a => a.Create(It.IsAny<Widget>()), Times.Once());
Assert.IsNotNull(localWidget);
Assert.AreEqual("Derived.Name", localWidget.DerivedName);
}
I feel that this approach is less error prone since it is more explicit, and it's easier to see that the Assert statements will be called. Is one approach preferable to the other? Is there a simpler way to test the input parameter passed to a mock that I'm missing?
In case it is helpful, here is the rest of the code for this example:
public class Widget
{
public string Name { get; set; }
public string DerivedName { get; set; }
}
public class WidgetCreatorPresenter
{
private readonly IWidgetCreator _creator;
public WidgetCreatorPresenter(IWidgetCreator creator)
{
_creator = creator;
}
public void Save(string name)
{
_creator.Create(
new Widget { Name = name, DerivedName = GetDerivedName(name) });
}
//This is the method I want to test
private static string GetDerivedName(string name)
{
return string.Format("Derived.{0}", name);
}
}
public interface IWidgetCreator
{
void Create(Widget widget);
}
EDIT
I updated the code to make the second approach I outlined in the question easier to use. I pulled creation of the expression used in Setup/Verify into a separate variable so I only have to define it once. I feel like this method is what I'm most comfortable with, it's easy to setup and fails with good error messages.
[Test]
public void Properly_Generates_DerivedName()
{
var widgetCreator = new Mock<IWidgetCreator>();
Widget localWidget = null;
Expression<Action<IWidgetCreator>> expressionCreate =
(w => w.Create(It.IsAny<Widget>()));
widgetCreator.Setup(expressionCreate)
.Callback((Widget widget) => localWidget = widget);
var presenter = new WidgetCreatorPresenter(widgetCreator.Object);
presenter.Save("Name");
widgetCreator.Verify(expressionCreate, Times.Once());
Assert.IsNotNull(localWidget);
Assert.AreEqual("Derived.Name", localWidget.DerivedName);
}
What I do is do the Verify with matches in keeping with AAA. And becuase of this the Setup is not required. You can inline it but I separated it out to make it look cleaner.
[Test]
public void Properly_Generates_DerivedName()
{
var widgetCreator = new Mock<IWidgetCreator>();
var presenter = new WidgetCreatorPresenter(widgetCreator.Object);
presenter.Save("Name");
widgetCreator.Verify(a => a.Create(MatchesWidget("Derived.Name"));
}
private Widget MatchesWidget(string derivedName)
{
return It.Is<Widget>(m => m.DerivedName == derivedName);
}
Because of the way your code is structured, you're kind of forced to test two things in one unit test. You're testing that A) your presenter is calling the injected WidgetCreator's create method and B) that the correct name is set on the new Widget. If possible, it'd be better if you can somehow make these two things two separate tests, but in this case I don't really see a way to do that.
Given all that, I think the second approach is cleaner. It's more explicit as to what you're expecting, and if it fails, it'd make perfect sense why and where it's failing.
Just to elaborate on #rsbarro's comment - the Moq failure error message:
Expected invocation on the mock at least once, but was never performed
... is less than helpful for complex types, when determining exactly which condition actually failed, when hunting down a bug (whether in the code or unit test).
I often encounter this when using Moq Verify to verify a large number of conditions in the Verify, where the method must have been called with specific parameter values which are not primitives like int or string.
(This is not typically a problem for primitive types, since Moq lists the actual "performed invocations" on the method as part of the exception).
As a result, in this instance, I would need to capture the parameters passed in (which to me seems to duplicate the work of Moq), or just move the Assertion inline with Setup / Callbacks.
e.g. the Verification:
widgetCreator.Verify(wc => wc.Create(
It.Is<Widget>(w => w.DerivedName == "Derived.Name"
&& w.SomeOtherCondition == true),
It.Is<AnotherParam>(ap => ap.AnotherCondition == true),
Times.Exactly(1));
Would be recoded as
widgetCreator.Setup(wc => wc.Create(It.IsAny<Widget>(),
It.IsAny<AnotherParam>())
.Callback<Widget, AnotherParam>(
(w, ap) =>
{
Assert.AreEqual("Derived.Name", w.DerivedName);
Assert.IsTrue(w.SomeOtherCondition);
Assert.IsTrue(ap.AnotherCondition, "Oops");
});
// *** Act => invoking the method on the CUT goes here
// Assert + Verify - cater for rsbarro's concern that the Callback might not have happened at all
widgetCreator.Verify(wc => wc.Create(It.IsAny<Widget>(), It.Is<AnotherParam>()),
Times.Exactly(1));
At first glance, this violates AAA, since we are putting the Assert inline with the Arrange (although the callback is only invoked during the Act), but at least we can get to the bottom of the issue.
Also see Hady's idea of moving the 'tracking' callback lambda into its own named function, or better still, in C#7, this can be moved to a Local Function at the bottom of the unit test method, so the AAA layout can be retained.
Building on top of StuartLC's answer in this thread, you follow what he is suggesting without violating AAA by writing an "inline" function that is passed to the Verify method of a mock object.
So for example:
// Arrange
widgetCreator
.Setup(wc => wc.Create(It.IsAny<Widget>(), It.IsAny<AnotherParam>());
// Act
// Invoke action under test here...
// Assert
Func<Widget, bool> AssertWidget = request =>
{
Assert.AreEqual("Derived.Name", w.DerivedName);
Assert.IsTrue(w.SomeOtherCondition);
Assert.IsTrue(ap.AnotherCondition, "Oops");
return true;
};
widgetCreator
.Verify(wc => wc.Create(It.Is<Widget>(w => AssertWidget(w)), It.Is<AnotherParam>()), Times.Exactly(1));