I have a controller method that throws a custom exception if a loop through a list of ids doesn't find a specified id, otherwise it returns a partial view.
I've done the test to see if it successfully returns a partial view but how do I test that the method fails and that the custom exception is thrown?
You can do a simple try/catch and perform Assert.Fail if you don't catch the expected exception. However, most unit testing frameworks provide an automated way of testing for exceptions.
Microsoft's MSTest has the ExpectedException attribute which can be applied to a test method:
[ExpectedException(typeof(ArgumentNullException))]
[TestMethod]
public void DoSomething()
{ ... }
If the test method above does NOT throw an ArgumentNullException, MSTest will mark the test as a fail.
NUnit has a more granular Assert.Throws that gives you more specific control of exactly where in the test method an exception is expected.
Related
How do I use TestNG throw new SkipException() effectively? Does anyone have an example?
I tried throwing this exception at the start of a test method but it blows up the teardown, setup, methods, etc. , and has collateral damage by causing a few (not all) of the subsequent tests to be skipped also, and shows a bunch of garbage on the TestNG HTML report.
I use TestNG to run my unit tests and I already know how to use an option to the #Test annotation to disable a test. I would like my test to show up as "existent" on my report but without counting it in the net result. In other words, it would be nice if there was a #Test annotation option to "skip" a test. This is so that I can mark tests as ignored sortof without having the test disappear from the list of all tests.
Is "SkipException" required to be thrown in #BeforeXXX before the #Test is ran? That might explain the wierdness I am seeing.
Yes, my suspicion was correct. Throwing the exception within #Test doesn't work, and neither did throwing it in #BeforeTest, while I am using parallel by classes. If you do that, the exception will break the test setup and your TestNG report will show exceptions within all of the related #Configuration methods and may even cause subsequent tests to fail without being skipped.
But, when I throw it within #BeforeMethod, it works perfectly. Glad I was able to figure it out. The documentation of the class suggests it will work in any of the #Configuration annotated methods, but something about what I am doing didn't allow me to do that.
#BeforeMethod
public void beforeMethod() {
throw new SkipException("Testing skip.");
}
I'm using TestNG 6.8.1.
I have a few #Test methods from which I throw SkipException, and I don't see any weirdness. It seems to work just as expected.
#Test
public void testAddCategories() throws Exception {
if (SupportedDbType.HSQL.equals(dbType)) {
throw new SkipException("Using HSQL will fail this test. aborting...");
}
...
}
Maven output:
Results :
Tests run: 85, Failures: 0, Errors: 0, Skipped: 2
While using DataProvider empty test using Apache POI create seperate check #BeforeTest we can skip the data base is empty or null in that scenario we can use this skiptest with row check is empty using boolean true check then skipped that expection do not go to entire check its having 1000 input check rather its skip that data provider null...
For skipping test case from #Test annotation option you can use 'enable=false' attribute with #Test annotation as below
#Test(enable=false)
This will skip the test case without running it. but other tests, setup and teardown will run without any issue.
I'm reading "Dependency Injection for .NET" and following along with some of the samples in the book and it lead me to a question about unit testing.
How does a unit test know when to pass or fail?
Not sure why, but I've always assumed you needed to Assert something and if the Assert is true, the unit test passes otherwise the test fails.
However, that seems to be not the case. Look at this sample below (using NUnit and Moq).
[Test]
public void Test_UserProvidedMessage()
{
Mock<IMessageWriter> m = new Mock<IMessageWriter>();
Salutation s = new Salutation(m.Object);
s.Exclaim("use this message silly");
m.Verify(w => w.Write("use this message silly"));
}
The unit test output is controlled through the Mock.Verify method. I understand that for this example but now I'm questioning what I know about unit tests passing or failing.
How does a unit test know when to pass or fail?
What criteria does the unit test framework use to determine if the output is pass or fail?
A unit test fails if it throws an exception.
All assertion methods and mock verifiers throw special exceptions that provide more detail about the failure.
I'm guessing maybe the Verify method throws an exception if it can't verify, and this causes the unit test to fail. And if there's no exception it means it passed.
I'm fairly new to unit testing and can't get around how to test (or if I even should) this case properly.
I have a controller method (pseudo code):
public ActionResult Register(formModel model)
{
if (ModelState.isValid) {
try {
_userService.CreateUser(a bunch of parameters here);
return RedirectToAction(some other action);
}
catch (Exception e)
{
ModelState.AddModelError("",e.Message);
}
}
return View();
}
I have a bunch of separate tests against "_userService". The "CreateUser" method just creates a new user and returns nothing OR throws an exception if there was an error (ex. the user exists) that I bubble up to the controller surround in a try catch and add the exception to the ModelState.
From what I understand I should mock the service and assert that it was called correctly (i use the assertwascalled syntax) since it returns nothing and I just want to know that my controller calls it.
What I'm not sure is how to test that when the userservice throws an error it should not redirect and should add that exception to the modelstate. With rhino mocks you can stub a mock but the book art of unit testing advises against that.
Right now in my test I manually add a model error (not caring if it's from user service) and test that the controller returns the same view if there are errors. Is this the correct way of going about this? Or should I maybe create a separate test where I stub the _userService to throw an error and check it gets added to modelstate? Or should I not even test that case? I feel like I may be just over analyzing the whole thing and testing using the modelstate would be enough to satisfy this...
Your mock represents a collaborating class. I wouldn't get too hung up on the difference between mocks and stubs; it's still a collaborating class.
You can think of your unit tests as describing how to use your class, and how the class then interacts with its collaborators. You have two examples:
Given a controller
When I register the model
Then the class should ask the user service to create a user.
And:
Given a controller
Given the user service is broken
When I register the model
Then the class should attach the error to the model state.
It's that second Given that tells you you're stubbing rather than mocking. You're setting the user service up as though it's broken. The context in which the class acts is different, so you need to stub, and you should indeed throw an exception.
If you put these lines as comments inside your test, it'll make sense. If it makes sense, ignore the book.
BTW, this is unit-level BDD. You can use "Given, When, Then" at a unit level just as at a scenario level, and it might help you think about the logic of your tests. Just don't use BDD scenario tools for this.
I'm writing unit tests (using NUnit & Moq) for my MVC 2 controllers, and am following examples in the Pro ASP.net MVC 2 Framework book by Steven Sanderson (great book, btw). However, I've run into problems, which I think are just due to my lack of understanding of NUnit.
Here's an excerpt, with the irrelevant parts removed:
[Test]
public void Cannot_Save_Invalid_Event()
{
...
repository.Setup(x => x.SaveEvent(evt)).Callback(Assert.Fail);
...
repository.Verify(x => x.SaveEvent(evt));
}
This test is passing for me, although from what I understand, those two statements should directly conflict with each other. The second one wasn't there originally, but I put it in to verify that it was passing for the right reasons.
From what I understand, my repository is set up to fail if "repository.SaveEvent(evt)" is called. However, later in the test, I try to verify that "repository.SaveEvent(evt)" was called. Since it passes, doesn't this mean that it was both called, and not called? Perhaps those statements don't act as I suspect they do.
Can someone explain how these two statements are not opposites, and how they can both exist and the test still pass?
Maybe your tests doesn-t fail beacuse it has a catch-everything block that also hides the assert/verify-exception that is necessary for the test to fail.
Note: the following unittest will allways pass
[Test]
public void HidingAssertionFailure()
{
try {
Assert.AreEqual(0,1); // this should fail
} catch (Exception ex) {
// this will hide the assertion failure
}
}
The reason for this behavior was that it was running "SaveEvent()", however, since the mocked repository didn't define that action, it was throwing an exception in my controller, which my controller was catching.
So, it seems that the callback will only execute if control returns successfully.
At my company we are writing a bunch of unit tests. What we'd like to have done is for the unit tests to execute and whenever one succeeds or fails at the end of the test we can write that somewhere but we don't want to put that logic in every test.
Any idea how we could just write tests without having to surround the content of the test with the try catch logic that we've been using?
I'm guessing you do something like this:
[Test]
public void FailBecauseOfException()
{
try
{
throw new Exception();
}
catch (Exception e)
{
Assert.Fail(e.Message);
}
}
There is no need for this. The tests will fail automatically if they throw an exception. For example, the following test will show up as a failure:
[Test]
public void FailBecauseOfException()
{
throw new Exception();
}
I'm not entirely sure what you are trying to do here. Are you saying you are wrapping it in a try/catch so that you can catch when an exception occurs and log this?
If so, then a better way, probably, is just to get NUnit to write an output file and use this. I haven't used NUnit for about a year, but IIRC you can redirect its output to any file you like using the /out directive.
If there is a reason why you have to log it the way you say, then you'll either have to add your custom code to each test, or have a common "runner" that takes your code (for each test) as an anonymous method and runs it inside a single try..catch. That would prevent you having to repeat the try..catch for every test.
Apologies if I've misunderstood the question.
MSTest has TestCleanup, which runs after every test. In NUnit, the attribute to be used is TearDown (after every test) or TestFixtureTearDown (after all the test are completely). This executes after the end of each test.
If you want something to run just in case a test passes, you could have a member variable shouldRunExtraMethod, which is initialized to false before each test, and is changed to true at the end of the test. And on the TearDown, you only execute it depending on this variable value
If your unit test method covers the scenario in which you expect exceptions to be thrown, use the ExpectedException attribute. There's a post here on SO about using that attribute.
Expect exceptions in nUnit...
NUnit assert statements all have an option to print a message for each test for when it fails.
Although if you'd like to have it write out something somewhere at the end of each test, you can set it up in the teardown of each method. Just set the string to what you want written inside the test itself, and during teardown (which happens after each test) It can do whatever you want with it.
I'm fairly certain teardown occurs even if an exception is thrown. That should do what you're wanting.
The problem you have is that the NUnit Assert.* methods will throw an AssertionException whenever an assert fails - but it does nothing else. So it doesn't look like you can check anything outside of the unit test to verify whether the test failed or not.
The only alternative I can think of is to use AOP (Aspect Oriented Programming) with a tool such as PostSharp. This tool allows you to create aspects that can act on certain events. For example:
public class ExceptionDialogAttribute : OnExceptionAspect
{
public override void OnException(MethodExecutionEventArgs eventArgs)
{
string message = eventArgs.Exception.Message;
Window window = Window.GetWindow((DependencyObject) eventArgs.Instance);
MessageBox.Show(window, message, "Exception");
eventArgs.FlowBehavior = FlowBehavior.Continue;
}
}
This aspect is code which runs whenever an exception is raised:
[ExceptionDialog]
[Test]
public void Test()
{
assert.AreEqual(2, 4);
}
Since the above test will raise an exception, the code in ExceptionDialogAttribute will run. You can get information about the method, such as it's name, so that you can log it into a file.
It's been a long time since I used PostSharp, so it's worth checking out the examples and experimenting with it.