I truly love NUnit's new(er) ability to test for expected exception testing, ie:
var ex = Assert.Throws<SomeException>(()=>methodToThrowException("blah"));
One minor issue I find is that to test some sort of operator overload or other assignment type functionality, the only way I can know how to do this is by giving the compiler a variable to assign to, like so:
// test division operator "/"
var ex = Assert.Throws<PreconditionException>(() => { var ignored = nbr / m; });
This is compact and works great, but has the annoyance where Resharper puts out a warning that the variable ignored is never used. This is counter productive if you like to use Resharper visuals to help you judge the quality of the code at a glance, as I do. Resharper is technically correct of course, but is there a way to tell Resharper this is my intention? I have a test with a lot of these sorts of tests, so a pragma will look nasty.
Any suggestions (besides "get over it, dude")?
Cheers
You could write your own Throws method which takes a Func<object> instead, and then just write:
var ex = Assert.Throws<PreconditionException>(() => nbr / m);
Then submit the new method to NUnit and wait for the next release :)
Add a field to the unit test and suppress the warning, ie:
// ReSharper disable UnaccessedField.Local
private object _ignore;
// ReSharper restore UnaccessedField.Local
The use that field as the assignment variable in your test delegate:
// test division operator "/"
var ex = Assert.Throws<PreconditionException>(() => { _ignore = nbr / m; });
This keeps resharper quiet, so you know if it does complain about something now it is likely a legitimate complaint that should be looked at. This eliminates the noise level so you can focus (I have over 50 tests like this in an important class that needs some refactoring).
Cheers,
Berryl
And it's really neat you can get the exception and work with it ...
var exception = Assert.Throws<ArgumentException>(() => dlinvalid.ProcessData());
Assert.That(exception.Message, Is.EqualTo("foo bar"), "Expected bar foo");
Plus it works with Resharper, whereas ExpectedException seems to be failing with NUnit 2.5
Related
I have a requirement to not run a test case during certain times in the month and I would like to ignore or skip the relevant test(s) when applicable. So far the only attribute I have found that makes sense is Assert.Ignore();. Unfortunately triggering this method throws an IgnoreException and as a consequence the NUnit TearDown will not be triggered. This is not ideal as I have code that I would like to execute after each test case irrespective of the test outcome. I was incorrect in my assumption please find comments below...
In an ideal world I wish I could just set the test outcome in my ignore / skipped part of the code, example:
else
{
//it's after the 25th of the month let's skip this test case
TestContext.CurrentContext.Result.Outcome == ResultState.Ignored;
}
But I understand that TestContext.CurrentContext.Result.Outcome is only a Get for good reason and it would most likely just open a can of worms with people just setting their tests as passed when they should not etc..
[Test]
[TestCase(TestName = "Test A")]
[Description("Test A will be testing something.")]
[Category("Regression Test Pack")]
public void Test_Case_1()
{
sessionVariables = new Session().SetupSession(uiTestCase: true);
if (DateTime.Now.Day <= 25)
{
//let's test something!
}
else
{
//it's after the 25th of the month let's skip this test case
Assert.Ignore();
}
}
[TearDown]
public void Cleanup()
{
sessionVariables.TeardownLogic(sessionVariables);
}
As you discovered, use of Assert.Ignore does not cause the teardown to be skipped. (If it did, that would be an NUnit bug, because teardown must always be run if setup has been run)
So, your choice of how to end the test depends on how you want the result to be shown...
Simply returning causes the test to pass, without any special message.
Assert.Pass does the same thing but allows you to include a message.
Assert.Ignore issues an "ignored" warning and allows you to specify a reason. The warning is propagated so that the result of the run as a whole is also "Warning".
Assert.Inconclusive gives an "inconclusive" result, which is intended to mean that the test could not be run due to some external factor. You may also specify the specific reason and the overall run result is not affected.
As an alternative to Assert.Inconclusive, you could use Assume.That with an appropriate test. For example, the following code would trigger the "inconclusive" result after the 25th of the month:
Assume.That(DateTime.Now.Day <= 25);
For what it's worth, the "Inconclusive" result is intended for exactly this kind of situation. It means that the test could not be run for reasons beyond it's control. "Ignored" results are intended to be treated as a problem to eventually be solved by the team, although many folks use it differently.
From the point of view of NUnit's design, Assume.That is the most natural way to produce the result. You would normally place it at the beginning of the test or the SetUp method, before any other code.
You can just return instead of doing an assert.
public void Test_Case_1()
{
sessionVariables = new Session().SetupSession(uiTestCase: true);
if (DateTime.Now.Day <= 25)
{
//let's test something!
}
else
{
//it's after the 25th of the month let's skip this test case
return;
}
}
Playing around with Rhino Mocks, i just stumbled upon a strange behaviour, which I cannot understand.
Setting up my Stub the following way works as expected - 42 is returned
var generator = MockRepository.GenerateStub<INumberGenerator>();
generator.Stub(x => x.GetNumber()).Return(42);
Then I tried using the WhenCalled(Action<MethodInvocation> action) extension, which I used so far only for void functions:
generator.Stub(x => x.GetNumber()).WhenCalled(mi => mi.ReturnValue = 42);
This code throws me an exception Method 'INumberGenerator.GetNumber();' requires a return value or an exception to throw.. Ok, I've added .Return(55) - and now things start to get weird:
generator.Stub(x => x.GetNumber()).WhenCalled(mi => mi.ReturnValue = 42).Return(55);
Which now returns 42, instead of 55. Note that the MethodInvocation.ReturnValue only works when adding the .Return(..) statement which then has absolutely no effect on the returnvalue - which confuses me a lot. Can anybody explain this behaviour?
Rhino Mocks requires you to specify a Return() call at the end of an Expect() chain (in your case, when you're setting expectation for your stub), so that it can determine the type of the return result.
So, in effect, the return value in WhenCalled() is only used. Any value in Returns() would do (and not be used) as long as it is of the same type.
Not explicitly mentioned in the documentation I think.
Referring to this question:
Moq how to replace obsolete expression
I have the following:
[Test]
public void OnSearchRequest_ViewFiresEvent_EventIsHandled()
{
// Arrange
Mock<IViewUsers> view = new Mock<IViewUsers>();
Users users = new Users(view.Object);
// Act
view.Raise(v => v.SearchForUsers += null, this, new SearchEventArgs());
// Assert
view.VerifySet(v=> v.SearchResult = It.IsAny<List<IUser>>());
}
originally I had:
// Assert
view.VerifySet(v => v.SearchResult);
But was getting the warning:
'Moq.MockExtensions.VerifySet(Moq.Mock,
System.Linq.Expressions.Expression>)' is
obsolete: 'Replaced by VerifySet(Action)'
So I found the question referenced above, and changed it to match, but now I'm STILL getting that warning, and on top of that, a hard error on "v.SearchResult" within the call to VerifySet :
An expression tree may not contain an assignment operator.
I can't see that I'm formatting this improperly - so why isn't it recognizing this as an action as the other question implies it should?
I found something relatively close to what you are asking about. Moq how to replace obsolete expression I don't know if this helps because I only ever used mock.Setup and mock.Verify.
Also as mentioned before try using lambda expressions within your It.IsAny to pinpoint smaller things this way . If a verify fails you know exactly where it failed. Especially if you are expecting a value at a certain position for example.
I don't know if it helps, but I've had problems in the past using It.IsAny<> with lists. Could you try something like It.Is<List<IUser>>(l => l != null)?
I just read this post and it makes the case against implicit typing using when starting out with Test driven development/design.
His post says that TDD can be "slowed down" when using implicit typing for the return type when unit testing a method. Also, he seems to want the return type specified by the test in order to drive development (which makes sense to me).
A given unit test with implicit typing might look like this:
public void Test_SomeMethod()
{
MyClass myClass = new MyClass();
var result = myClass.MethodUnderTest();
Assert.AreEqual(someCondition, result);
}
So my questions are:
Does using implicit typing help or hinder writing unit tests for TDD? Is there anyone out there that can share their experience using this technique when writing unit tests?
I ask this because soon I have not done TDD and want to know if there is a way to write generic or semi-generic unit tests that would work a return type might change.
I see his point but I don't really think it's the right reason to not use var here. Remember, TDD works roughly according to the following:
Write a new test.
If test fails to compile (and it should fail!), write enough code until the test compiles.
Run all tests.
If a test fails, write enough code until all tests pass.
Refactor.
Whether or not we use var the test will fail to compile either way because the method under test won't exist yet!. Once we start coding up NewMethod his points are rather moot.
Rather, the right reason to not use var here is because the code gives no indication what the type of result is. This is a matter of opinion but var is okay here
var dict = new Dictionary<Foo, List<Bar>>();
and for anonymous types but not here
var m = M();
because it's completely unclear without going to the declaration of M (or using IntelliSense) what the return type of M is.
Yes and No
In Visual Studio presently, TDD is a bit of a pain, especially when using implicity typing. var means no intellisense, then when you enter the name of a type that may not exist yet it has the tendency to auto-complete with something that is similiar to what you are typing, often the name of the test fixture.
Visual Studio 2010 has a consume first mode, which makes it ideal and better for Test Driven Development. Currently you'll find (in 2008 and earlier) you have to hit escape to hide intellisense.
As for use of var it's purely synatic sugar. It makes the following much nicer in my opinion:
var type = new MyType();
Its clear that the variable type, is of type MyType. var is great for generics and follows the prinicple of DRY - Don't Repeat Yourself.
var type = MethodCall();
var result = ReturnResult();
On the other hand, this makes for hard to read code, whether you follow TDD or not. Good unit tests should flow and be easy to read. If you have to think, or hover the mouse over a method to see the return type, that is the sign of a bad, hard to read test.
From a tooling perspective, I'd say it's nicer to avoid the var. I use Eclipse and Java, but I know that extensions like CodeRush and Resharper offer many of the features that I'm discussing here. When in my test I call a method that doesn't exist yet, I can "quick fix" it to create the method in the desired class. The return type of the automatically created method depends on its context; if I am expecting back a String, the return type of the method will be String. But if the assignment is to a var (which Java doesn't have - but if it did), the IDE wouldn't know enough to make the return type anything other than var (or maybe Object).
Not everyone uses the IDE in this way in TDD, but I find it very helpful. The more information I can give the IDE in my test, the less typing I have to do to make the test pass.
How do I verify that method was NOT called in Moq?
Does it have something like AssertWasNotCalled?
UPDATE: Starting from Version 3.0, a new syntax can be used:
mock.Verify(foo => foo.Execute("ping"), Times.Never());
Run a verify after the test with the Times.Never() option.
_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(), Times.Never());
UPDATE: Since version 3, check the update to the question above or Dann's answer below.
Either, make your mock strict so it will fail if you call a method for which you don't have an expect
new Mock<IMoq>(MockBehavior.Strict)
Or, if you want your mock to be loose, use the .Throws( Exception )
var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Stolen from: John Foster's answer to the question, "Need help to understand Moq better"
One of the things that you might want to test is that the pay method
does not get called when a person aged over 65 is passed into the
method
[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {
var mockPensionService = new Mock<IPensionService>();
var person = new Person("test", 66);
var calc = new PensionCalculator(mockPensionService.Object);
calc.PayPensionContribution(person);
mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never);
}
This does not work in recent versions of Moq (since at least 3.1), it should be specified in the Verify method as mentioned in the
answer.
Actually, it's better to specify .AtMost(0) after the Returns statement.
var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);
Although the "throws" also works, AtMost(0) is more expressive IMHO.
Using VerifyNoOtherCalls (requires Moq 4.8 or later)
This answer is an indirect approach. Instead of checking that a particular method wasn't called, you check that no unexpected calls were made in general.
Consider that a thorough test of a mock does 2 things:
Verify that all expected calls were made
Verify that no unexpected calls were made
If you're already doing step 1, adding step 2 is trivial:
// Step 1 (if relevant - see note below)
mock.Verify(..., Times.Exactly(2));
mock.Verify(..., Times.Once());
// ...
// Step 2
mock.VerifyNoOtherCalls();
Notes
If you omit step 1, step 2 will simply ensure no calls were made to the mock at all.
This does not require a strict mock.
Source: Moq Quickstart
I realise this is a very old question, but it just appeared in my sidebar, and I'd like to add my solution.
Many unit tests appear to mock several functions, as part of the setup, but then aren't used during the test.
Surely it's better to enable strict mocking (which means anything not explicitly setup will throw an exception), and then don't set up any functions you don't expect to be called. Or to put it another way, only set up the functions that one test expects to be called, and anything else will thrown an exception.
var thingBeingTested = new Mock<IThink>(MockBehaviour.Strict);
thingBeingTested.ThisWillThrowAnExceptionBecauseItHasNotBeenMocked();
Suppose you have this method and you want to test that it's not being called
//Setup
var databaseSessionMock = new Mock<IDatabaseSession>();
databaseSessionMock.Setup(m => m.Commit()).Returns(true).Verifiable();
RepositoryFactory.Configure<IDatabaseSession>(databaseSessionMock.Object);
you can test like this
databaseSessionMock.Verify(m => m.Commit(It.IsAny()), Times.Never(), "Database Session mock object was not used");
Use .AtMostOnce();
After the real test, call the method again. If it throws an exception, it was called.