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
Related
I'm trying to write a code analysis rule with roslyn.
Basically, I have to check whether an each of arguments which a Microsoft.Practices.Prism.Commands.DelegateCommand() is created is wrapped in try catch or not.
The main idea is collect all ObjectCreationExpressionSyntax objects of DelegateCommand class and check each constructor's argument if the first StatementSyntax is TryStatementSyntax or not.
Can you help me with getting all StatementSyntax from ArgumentSyntax ? Or may be you have an another approach ?
public IEnumerable<IdentifierInfo> Collect(SyntaxNode rootNode, SemanticModel semanticModel)
{
ObjectCreationExpressionSyntax[] objCreation = rootNode
.DescendantNodes()
.OfType<ObjectCreationExpressionSyntax>()
.Where(c=>(c.Type as IdentifierNameSyntax)?.Identifier.Value.ToString() == "DelegateCommand")
.ToArray();
foreach (var obj in objCreation)
{
var args = obj.ArgumentList.Arguments;
foreach (ArgumentSyntax arg in args)
{
var expession = arg.Expression;
var symbol = semanticModel.GetSymbolInfo(expession).Symbol as IMethodSymbol;
}
}
}
Bellow you can find what I actually compile for searching through:
public class Program
{
public delegate void MyDelegate();
public static void DelegateMethod() { try { } catch { } }
public static void Main(string[] args)
{
DelegateCommand del1 = new DelegateCommand(() => {try{}catch{}});
DelegateCommand del2 = new DelegateCommand(new Action(() => { }));
DelegateCommand del3 = new DelegateCommand(DelegateMethod);
var barInit = (Action)(DelegateMethod);
DelegateCommand del4 = new DelegateCommand(barInit);
ICommand test;
test = new Microsoft.Practices.Prism.Commands.DelegateCommand(() => { });
}
}
You start in a good way, but to handle it completely, its required more work.
Lets see in your example what we have
(The screenshot is from LINQ debugging feature from OzCode)
Here what I wrote is
var argsExpr = objCreation.Select(o => o.ArgumentList.Arguments.First())
As you can see in the right side of the window, we have a three types of syntax nodes in the arguments, so we don't have a general way to handle them all.
You have two ways to handle it.
Write method that get SyntaxNode and according to its type, check if the first statement is a try\catch statement
Write SyntaxWalker and visit relevant methods, and there, check if the first statement is a try\catch statement
For example to handle the first case which is ParenthesizedLambdaExpressionSyntax you need to write something like this (or by yourself or by overriding the appropriate Visit method of the SyntaxWalker)
public static bool IsTryStatement(ParenthesizedLambdaExpressionSyntax node)
{
return ((BlockSyntax) node.Body).Statements.First() is TryStatementSyntax;
}
This is just an example. In your real code you need to handle all cases.
For the IdentifierNameSyntax you need to get the method symbol first:
semanticModel.GetSymbolInfo(identifier).Symbol
Then you need to get the syntax node from DeclaringSyntaxReferences and use span, or you can use location of the symbol or any other way (ConstructFrom maybe).
I'm looking for some advice on writing some unit tests for the code below. Implementation aside (it's not my code, but I've been tasked to retroactively write some tests for it) could someone suggest how I might test this? I'm not using nUnit or a similar framework; I am using the testing tools built into Visual Studio.
I'm fairly new to writing unit tests, but I imagine I should at least test the following:
Valid response passed into SaveFormBrokerResponse() method
Test for valid exceptions thrown by the catch()
Testing the started Task, but not sure how to do this
I've stripped just a bit out of this function, mostly to do with instantiation and population of some objects:
public void SaveResponse(IForm form, bool isLive, HttpRequestBase request)
{
try
{
var response = new FormBrokerResponses();
// Initialize some vars on response
using (var memory = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(FormKeyValue[]));
serializer.WriteObject(memory, request.Form.AllKeys.Select(r => new FormKeyValue(r, request.Form[r])).ToArray());
memory.Flush();
memory.Seek(0, SeekOrigin.Begin);
response.Values = Encoding.UTF8.GetString(memory.ToArray());
}
_dataHandler.SaveFormBrokerResponses(response);
}
catch (Exception ex)
{
throw new Exception("boom explosions");
}
Task.Factory.StartNew(() => DispatchFormResponseViaEmail(form, isLive, request.Form.AllKeys.ToDictionary(r => r, r => (object)request.Form[r])));
}
I realize that testing void implementations is tricky and questionable and that there are some integration test concerns here, but that said I can't (currently) change the implementation and need to write tests for what I have.
You can't. You've created a method that fires off an asynchronous operation and then doesn't expose any means of observing the completion/results of that operation to the caller. There are lots of ways of doing this (returning a task, accepting a callback, an event, etc.) but you need to do something for the caller to be able to observe the results of the asynchronous operation. If the method doesn't expose anything, then there is nothing that the caller can reliably do.
If you are allowed to make slight modifications to the code I would do the following which is just a small change anyway :
public void SaveResponse(IForm form, bool isLive, HttpRequestBase request)
{
try
{
var response = new FormBrokerResponses();
// Initialize some vars on response
using (var memory = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(FormKeyValue[]));
serializer.WriteObject(memory, request.Form.AllKeys.Select(r => new FormKeyValue(r, request.Form[r])).ToArray());
memory.Flush();
memory.Seek(0, SeekOrigin.Begin);
response.Values = Encoding.UTF8.GetString(memory.ToArray());
}
_dataHandler.SaveFormBrokerResponses(response);
}
catch (Exception ex)
{
throw new Exception("boom explosions");
}
Dispatch(form,isLive,request);
}
virtual void Dispatch(IForm form, bool isLive, HttpRequestBase request){
Task.Factory.StartNew(() => DispatchFormResponseViaEmail(form, isLive, request.Form.AllKeys.ToDictionary(r => r, r => (object)request.Form[r])));
}
I don't know what this class is named so suppose the class is named DutClass, you can now derive a different implementation of that class as following:
public class UnitTestClass : DutClass{
override Dispatch(){
//don't do anything or set a state variable that this method was called
}
}
Then instead of testing the DutClass you test the UnitTextClass which has a different implementation of the Dispatch method and does not start a Task at all. You can then test that in fact this method was called, test for the exceptions and so on.
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)) {}
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));
Using the new Rhino Mocks 3.5 Arrange/Act/Assert (AAA) Testing style, I'm having problems writing a test.
I have a method that calls a method on a repository class. ActivateFoo, where my Foo object has an IsActive property. The result of the ActivateFoo object should change the property.
Here is sample code:
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).Return(true);
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
I'm guessing that the key piece of code would be inbetween "ActivateFoo(foo))." and "Return(true);".
One point to clarify how the method chaining stuff works behind the scenes, If there is code written on the line I expect, does it matter if it is after Return() or before? (unless of course the solution is using the MethodOptions overload of Expect, or something else).
Thanks in advance for any help.
Thanks to AB Kolan this is the resulting code I used and works.
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).
Do(new Func<Foo, bool>(
delegate(Foo f) { f.IsActive = true; return true; }
));
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
I tend to not like to have to have extra methods of functions for single use of a test, preferring an inline delegate if possible.
To address the issue of is this something I should be doing or not as far as the design. As the names are there, this isn't the exact code and inside of the target.Activate() method. The code in Activate() does some checking and if needed, will do the repository ActivateFoo(), and then check the result of that operation and do other things.
So, it might be possible that at a later time I will have to refactor this out and separate the steps, but for now, I've got it to work.
Thanks
You might want to try something out like this using the Do handler. I honestly feel ActivateFoo should be void return type. But here's the code for ActivateFoo with bool return type.
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).
Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
private delegate bool ActivateFooDelegate(Foo f);
public bool ActivateFooDelegateInstance(Foo f)
{
f.IsActive = true;
return f.IsActive;
}
I was not really using this version of RhinoMocks yet, but in the old versions you would have to use a .Do(appropriate delegate) to set the flag and return the value (instead of .Return).
Please let me know if it works, if not I can play around with it.
From the looks of it, ActivateFoo should be a void method. And since you are mocking it out, you shouldn't be verifying that it changes anything on your object.
You would verify that the IsActive property is changed when you were testing your repository method ActivateFoo, not when you are testing the Activate method on the presenter.