I have this:
Expect.Once.On( someObj ).Method( "SomeMethod" )
.With(1) // correct value is 2, I want this to fail
.Will( Throw.Exception( new Exception() ) );
An exception is thrown by nmock when it detects that I put 1 instead of 2. However, the test is failing (red) instead of passing. How to make this test pass, even though I'm expecting an exception?
If you're using NUnit then you can do:
Assert.Throws<Exception>(() => { someObj.SomeMethod(1); });
You can also decorate the test with an ExpectedException attribute, although that will cause the test to pass if any Exception is thrown, rather than just the statement you want to test.
EDIT: If you're using MSTest, as far as I know, you can only use attributes to expect exceptions i.e.
[ExpectedException(typeof(Exception)]
public void TestMethod() { ... }
You should consider throwing a more specific exception type from your mock and expecting that type instead of a plain Exception.
You could also define your own method to replicate the NUnit functionality:
public static class ExceptionAssert
{
public static void Throws<T>(Action act) where T : Exception
{
try
{
act();
}
catch (T ex)
{
return;
}
catch (Exception ex)
{
Assert.Fail(string.Format("Unexpected exception of type {0} thrown", ex.GetType().Name));
}
Assert.Fail(string.Format("Expected exception of type {0}", typeof(T).Name));
}
}
[ExpectedException (typeof(Exception))]
Edit: thanks, don't have the studio right now and was not 100% sure about the syntax.
Related
In this test code, why does the test fail with an ArgumentNullException, despite that it is handled?
[Test]
public void ExceptionBehaviorTest()
{
// This works. An instance is returned
var testInstance = (TestClass)Activator.CreateInstance(typeof(TestClass), "Hello World");
Assert.NotNull(testInstance);
// This passes. Exception is generated and caught
Assert.Throws<ArgumentNullException>(() => new TestClass(null));
try
{
// This throws ArgumentNullException but the catch handler is not invoked. This fails the test
testInstance = (TestClass)Activator.CreateInstance(typeof(TestClass), (string)null);
Assert.Fail("Should not get here");
}
catch (ArgumentNullException)
{
}
}
private sealed class TestClass
{
public TestClass(string arg)
{
Argument = arg ?? throw new ArgumentNullException(nameof(arg));
}
public string Argument
{
get;
}
}
If I run the code in the debugger, it stops in the TestClass ctor, saying that the exception is not handled. But the calling function is visible in the stack, so the problem is not related to some part being executed on a different thread.
[Background: In my real-world code, I'm iterating over a bunch of classes and testing whether they have a ctor with a specific argument. This is to prevent runtime errors later, as the classes are constructed using dependency injection.]
This is in the documentation
TargetInvocationException
The constructor being called throws an
exception.
So you need to catch TargetInvocationException in this situation, also if you like you can use when though I am not sure it helps with your test much
catch (TargetInvocationException ex) when (ex.InnerException is ArgumentNullException)
{
Console.WriteLine("Caught");
}
How can I pass types into my unit tests?
public void MethodUnderTest()
{
try
{
var businessService = _businessService.DoWork();
}
catch (SomeException exception)
{
//do some stuff
}
catch (SomeOtherException exception)
{
//do other stuff
}
}
My unit test should be something like this:
[TestCase(typeof(SomeException))]
[TestCase(typeof(SomeOtherException))]
public void UnitTest(Exception exception)
{
_businessService.Setup(x=>x.DoWork).Throws.InstanceOf<exception>();
//verify that when we called DoWork, that the logic inside of one of the catches was executed
}
One way this can be implemented would be, by utilizing inferred generics ..
you will have a test case source in your test fixture.
public static List< Exception > Exceptions => new List< Exception >
{
new InvalidOperationException(),
new OverflowException()
};
and then modify your unit test method as :
[Test]
[TestCaseSource(nameof( Exceptions ))]
public void UnitTest<T>( T exception ) where T : Exception, new(){
_businessService.Setup(x=>x.DoWork).Throws.InstanceOf<T>();
//verify that when we called DoWork, that the logic inside of one of the catches was executed
}
Then the code would infer the types from the instance of the exceptions in the test case source. I can't think of a way to do this with out instantiating the exceptions ...
You haven't said what you have tried that didn't work. On the surface, it appears easy enough, but perhaps I don't understand what you want to do.
The example unit test you show is incorrect. It takes an Exception as an argument, but you are giving it a Type. Based on your title, the test method should accept a type. Then do something like...
[TestCase(typeof(SomeException))]
[TestCase(typeof(SomeOtherException))]
public void UnitTest(Type exceptionType)
{
Assert.That(()=>_businessService.Setup(x=>x.DoWork),
Throws.InstanceOf(exceptionType));
}
```
Did I misunderstand the problem?
I'm trying to run nunit test cases from the console application using reflection. I get an exception which is not handled by my catch block. Could you give an advice how to handle all the exceptions from the invoked test methods?
static void Main(string[] args)
{
// Take all classes of the current assebly to which TestFixture attribute is applied
var testClasses = Assembly.GetExecutingAssembly().GetTypes().Where(c =>
{
var attributes = c.GetCustomAttributes(typeof(TestFixtureAttribute));
return attributes.Any();
});
foreach (var testClass in testClasses)
{
var testMethods = testClass.GetMethods().Where(m =>
{
var attributes = m.GetCustomAttributes(typeof (TestAttribute));
return attributes.Any();
});
var instance = Activator.CreateInstance(testClass);
foreach (var method in testMethods)
{
try
{
Action action = (Action) Delegate.CreateDelegate(typeof (Action),
instance, method);
action();
}
catch (AggregateException ae)
{
Console.WriteLine(ae.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
It's really unclear why you're trying to do this, since there's already nunit-console that can run unit tests from a console application. It's also unclear what exception you don't think is being caught, but I suspect it's not the type you think it is. I took your code and put it into a fresh console application, along with some very basic tests:
[TestFixture]
public class SomeFailingTests
{
[Test]
public void Fails()
{
Assert.AreEqual(1, 0);
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void TestExceptionExpected()
{
}
[Test]
public void TestThrows()
{
throw new InvalidOperationException();
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void TestThrowsExpected()
{
throw new InvalidOperationException();
}
}
All of the tests that threw exceptions were caught by the line:
catch (Exception e)
This makes sense, since none of them threw an AggregateException. I suspect whichever test you are running is also not throwing one and is also being caught by your outer catch. A good start might be to rewrite this block as:
catch (Exception e)
{
Console.WriteLine(string.Format("{0}: {1}", e.GetType().Name, e.Message));
}
So that you can see any exception types that you aren't handling. At a very basic level, you may have to account for AssertionException for example.
If you want to support a similar feature set to other nunit runners you're also going to need to pay attention to the ExpectedException attribute on any methods you run and check to see if that exception is thrown when you invoke the method. You'll also need to check for the Ignored attribute...
As has been mentioned in my answer to this question, you may also need to pay attention to other test attributes such as TestCase and TestCaseSource if you want to capture all of the tests in the assembly.
Unless you're writing this as a learning exercise, you might want to reconsider your approach.
I working with MOQ framework for my testing.
I have a scenario in which I expect a fault exception to be thrown.
How can I verify it was thrown?
public void Koko(List<string?> list)
{
foreach(string? str in list)
{
if (str != null) someProperty.Foo(str);
else throw new FormatException();
}
}
If you want to verify an exception was thrown (by your own code) then Moq is not your tool of choice for that.
Simply use one of the unit test frameworks available.
Xunit/NUnit:
Assert.Throws<SomeException>(() => foo.Bar());
Fluent Assertions:
Action act = () => foo.Bar();
act.Should().Throw<SomeException>();
https://fluentassertions.com/introduction
http://www.nunit.org/index.php?p=exceptionAsserts&r=2.6.2
I may be mis-reading your intent, but as far as I can see there is no need to do anything to a mock in order to test that the exception has been thrown.
It looks like you have a class with a method Foo that takes a string - lets call this InnerClass
public class InnerClass {
public virtual void Foo(string str) {
// do something with the string
}
}
and a class which contains an InnerClass as a property (someProperty) which has a member Koko that takes a List<string> as a parameter
public class OuterClass {
private readonly InnerClass someProperty;
public OuterClass(InnerClass someProperty) {
this.someProperty = someProperty;
}
public void Koko(List<string> list) {
foreach (var str in list) {
if (str != null)
someProperty.Foo(str);
else
throw new FormatException();
}
}
}
NOTE: I cannot get List<string?> to compile - tells me that the underlying type (string) must be non-nullable. AFAIK, one only needs to make value types nullable, reference types are implicitly nullable.
It looks like you want to test that if you pass in a list of strings where any of them are null that a FormatException is thrown.
If so, then the only reason for a MOQ is to release us from worrying about the InnerClass functionality. Foo is a method, so, unless we are using strict mocks, we can just create an InnerClass mock with no other setup.
There is an attribute [ExpectedException] with which we can tag our test to verify that the exception has been thrown.
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void ExceptionThrown() {
var list = new List<string>() {
"Abel",
"Baker",
null,
"Charlie"
};
var outer = new OuterClass(new Mock<InnerClass>().Object);
outer.Koko(list);
}
This test will pass if a FormatException is thrown and fail if it is not.
Reading through these answers I realized there is yet another way to do this using NUnit. The following gets the exception text from an exception and verifies the error message text.
var ex = Assert.Throws<SomeException>(() => foo.Bar());
Assert.That(ex.Message, Is.EqualTo("Expected exception text");
And I couldn't get the decoration / attribute syntax to work (AlanT's answer above) using the latest version of NUnit -- not sure why, but it complained no matter what I tried to do.
Please read this Introduction to Moq. Here is the way to setup InvalidOperationException throwing when DoSomething method is invoked:
mock.Setup(foo => foo.DoSomething()).Throws<InvalidOperationException>();
Then simply verify if method was called. If it was called, then exception was raised
mock.Verify(foo => foo.DoSomething());
You can test that an Exception is thrown using NUnit Asserts:
Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>());
An old question but no source code actually showing what the solution was, so here's what I did:
var correctExceptionThrown = false;
try
{
_myClass.DoSomething(x);
}
catch (Exception ex)
{
if (ex.Message == "Expected message")
correctExceptionThrown = true;
}
Assert.IsTrue(correctExceptionThrown);
Note rather than checking the message, you can catch a particular type of exception (generally preferable).
Ok so I solved it in the following way.
Since the exception broke my test I put the method call in the Because block in try-catch.
Then I could use a simple Verify.
Thanks to all helpers...
If I want to test that a method throws an exception of a particular type, NUnit's ExpectedException attribute doesn't care about the actual type; if I throw a generic Exception before the method call, the test passes:
[Test, ExpectedException(typeof(TestCustomException))]
public void FirstOnEmptyEnumerable()
{
throw new Exception(); // with this, the test should fail, but it doesn't
this.emptyEnumerable.First(new TestCustomException());
}
If I want to check that the test throws the exact exception type, I have to do something manual like this:
[Test]
public void FirstOnEmptyEnumerable()
{
try
{
throw new Exception(); // now the test fails correctly.
this.emptyEnumerable.First(new TestCustomException());
}
catch (TestCustomException)
{
return;
}
Assert.Fail("Exception not thrown.");
}
Am I missing something?
I've never used ExpectedException, so I don't have any experience to share on this. An option is to Assert that it Throws directly inside the test. Something like this:
[Test]
public void FirstOnEmptyEnumerable()
{
Assert.Throws<TestCustomException>(() => this.emptyEnumerable.First(new TestCustomException()));
}
I find this approach more readable as you test for the exception exactly where you expect it to happen instead of saying "somewhere inside this function I except an exception to be thrown".
I always test for the string representation of the exception e.g.:
[Test, ExpectedException("Your.Namespace.TestCustomException")]
public void FirstOnEmptyEnumerable()
{
throw new Exception(); // with this, the test should fail, but it doesn't
this.emptyEnumerable.First(new TestCustomException());
}
Which seems to work fine for me.
If you want to use the ExpectedException(string) signature, the best practice would be to use typeof(Exception).Name and typeof(Exception).Namespace