How to expect an Exception

883 views
Skip to first unread message

Esqueleto

unread,
Aug 6, 2007, 11:06:06 PM8/6/07
to Rhino.Mocks
I have expect that a method called from a event throw an exception?

tkx in advance
Paulo Aboim Pinto

Ayende Rahien

unread,
Aug 6, 2007, 11:16:06 PM8/6/07
to Rhino...@googlegroups.com
You want Rhino Mocks to /catch/ the exception, or throw it?

David Laribee

unread,
Aug 6, 2007, 11:44:17 PM8/6/07
to Rhino...@googlegroups.com
To force an exception from a mock (Rhino Mocks):

ISomeService mockService = mockRepository.CreateMock<ISomeService>();

using (mockRepository.Record())
{
   Expect.Call (mockService.MethodThatThrowsException()).Throw(new MyCustomException);
}

using (mockRepository.Playback())
{
   TheUnit theUnit = new TheUnit(mockService);
   Assert.IsFalse(theUnit.WillThisWork ());
}

public class TheUnit()
{
   private readonly IMockService _service;

   public TheUnit(IMockService service)
   {
      _service = service;
   }
   public bool WillThisWork()
   {
       bool result = false;

       try
       {
           _service.MethodThatThrowsException();
           result = true;
       }
      catch (MyCustomException ex)
      {
        result = false;
      }  
     
      return result;
   }
}

This would be useful in the case that

To test an exception is raised in the unit under test (NUnit):

[Test, ExpectedException(typeof(MyCustomExceptionType)]
public void An_exception_is_raised_when_something_happens()
{
   TheUnit theUnit = new TheUnit();
   theUnit.ThisMethodHadBetterThrowAnException ();
--


/ Dave

http://thebeelog.com

David Laribee

unread,
Aug 6, 2007, 11:45:58 PM8/6/07
to Rhino...@googlegroups.com
Sorry, hasty send...

"This would be useful in the case that" ->

This would be useful in a scenario where you want to handle the exception and rethrow (shield) or do a compensating action in your catch block.

Esqueleto

unread,
Aug 7, 2007, 11:26:36 AM8/7/07
to Rhino.Mocks
Tkx for the reply

my first approach was this

[Test]
[ExpectedException(typeof(NullReferenceException))]
public void SavePostNullException()
{
// setup the PostSaved event
postEditViewMock.PostSaved += null;
IEventRaiser postSavedRaiser =
LastCall.IgnoreArguments().GetEventRaiser();

// record the expectation of call of this method
blogDataServiceMock.SavePost (null);
mocks.ReplayAll();

new PostPresenter(postEditViewMock, blogDataServiceMock);
postSavedRaiser.Raise(postEditViewMock, EventArgs.Empty);
}

With this test I want to raise an event and check if inside the method
SavePost the parameter is NULL and if it's null I want to throw an
exception.

I have my mocks.VerifyAll() in the TearDown method and this is the
error I get

Failures:
1) UnitTest.Tests.TestClass.SavePostNullException : TearDown :
System.InvalidOperationException : This action is invalid when the
mock object is in record state.
--TearDown
at Rhino.Mocks.Impl.RecordMockState.get_VerifyState () [0x00000]
at Rhino.Mocks.MockRepository.Verify (System.Object obj) [0x00000]
at Rhino.Mocks.MockRepository.VerifyAll () [0x00000]
at UnitTest.Tests.TestClass.TearDown () [0x00000] in /home/esqueleto/
Projects/MbUnitTest/UnitTest.Tests/TestClass.cs:34
at <0x00000> <unknown method>
at (wrapper managed-to-native)
System.Reflection.MonoMethod:InternalInvoke (object,object[])
at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00056] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:146


ok .. I'm recording the expectation befores de ReplayAll(), yes? Why
he is saying that?


tkx in advance
Paulo Aboim Pinto

Odivelas - Portugal

Esqueleto

unread,
Aug 7, 2007, 11:31:48 AM8/7/07
to Rhino.Mocks
another thing

If I don't use the [ExpectedException ... ] I get this:

1) UnitTest.Tests.TestClass.SavePostNullException :
System.NullReferenceException : Post object cannot be null


TearDown : System.InvalidOperationException : This action is invalid
when the mock object is in record state.

at UnitTest.Controller.BlogDataService.SavePost
(UnitTest.Controller.Post post) [0x00012] in /home/esqueleto/Projects/
MbUnitTest/UnitTest.Controller/Service/BlogDataService.cs:16
at UnitTest.Tests.TestClass.SavePostNullException () [0x00017] in /
home/esqueleto/Projects/MbUnitTest/UnitTest.Tests/TestClass.cs:62


at <0x00000> <unknown method>
at (wrapper managed-to-native)
System.Reflection.MonoMethod:InternalInvoke (object,object[])
at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00056] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:146
--TearDown
at Rhino.Mocks.Impl.RecordMockState.get_VerifyState () [0x00000]
at Rhino.Mocks.MockRepository.Verify (System.Object obj) [0x00000]
at Rhino.Mocks.MockRepository.VerifyAll () [0x00000]
at UnitTest.Tests.TestClass.TearDown () [0x00000] in /home/esqueleto/
Projects/MbUnitTest/UnitTest.Tests/TestClass.cs:34
at <0x00000> <unknown method>
at (wrapper managed-to-native)
System.Reflection.MonoMethod:InternalInvoke (object,object[])
at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00056] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:146


what I want is to test that this method is been thrown.


tkx in advace


Paulo Aboim Pinto
Odivelas - Portugal


On Aug 7, 4:44 am, "David Laribee" <lari...@gmail.com> wrote:

> theUnit.ThisMethodHadBetterThrowAnException();

Ayende Rahien

unread,
Aug 7, 2007, 2:10:02 PM8/7/07
to Rhino...@googlegroups.com
Looks like blogDataServiceMock.SavePost() is not a virtual method

On 8/7/07, Esqueleto <esqu...@tusofona.com > wrote:

Esqueleto

unread,
Aug 8, 2007, 8:01:39 PM8/8/07
to Rhino.Mocks
Ok .. the method blogDataServiceMock.SavePost() is virtual. Now I
always get the message:


Failures:
1) UnitTest.Tests.TestClass.SavePostNullException :
System.NullReferenceException was expected


I try to use the other way of testing the Exception


[Test]


public void SavePostNullException()
{
// setup the PostSaved event
postEditViewMock.PostSaved += null;
IEventRaiser postSavedRaiser =
LastCall.IgnoreArguments().GetEventRaiser();

// record the expectation of call of this method

Expect.Call(blogDataServiceMock.SavePost(null)).Throw(new
NullReferenceException);
mocks.ReplayAll();

new PostPresenter(postEditViewMock, blogDataServiceMock);
postSavedRaiser.Raise(postEditViewMock, EventArgs.Empty);

mocks.VerifyAll();
}

LIke the example made by David Laribee, but even with this I get error
and cannot compile it. At this line I get the error

Expect.Call(blogDataServiceMock.SavePost(null)).Throw(new
NullReferenceException);
[Task:File=/home/esqueleto/Projects/MbUnitTest/UnitTest.Tests/
TestClass.cs, Line=64, Column=79, Type=Error, Priority=Normal,
Description=A new expression requires () or [] after type(CS1526)]

If I do

Expect.Call(blogDataServiceMock.SavePost(null)).Throw(new
NullReferenceException());

I get the errors
[Task:File=/home/esqueleto/Projects/MbUnitTest/UnitTest.Tests/
TestClass.cs, Line=64, Column=32, Type=Error, Priority=Normal,
Description=Cannot convert type `void' to `object'(CS1503: Argument
1)]
[Task:File=/home/esqueleto/Projects/MbUnitTest/UnitTest.Tests/
TestClass.cs, Line=64, Column=32, Type=Error, Priority=Normal,
Description=The best overloaded method match for
`Rhino.Mocks.Expect.Call(object)' has some invalid arguments(CS1502)]


How can I expect that some expectation is throw by a method that I'm
testing?

tkx in advace
Paulo Aboim Pinto
Odivelas - Portugal

On Aug 7, 7:10 pm, "Ayende Rahien" <aye...@ayende.com> wrote:
> Looks like blogDataServiceMock.SavePost() is not a virtual method
>

Esqueleto

unread,
Aug 8, 2007, 8:51:32 PM8/8/07
to Rhino.Mocks
OK .. I change a little bit the code but still cannot test the
exception. The code if the Unit Test is:

[Test]
[ExpectedException(typeof(NullReferenceException))]


public void SavePostNullException()
{
// setup the PostSaved event
postEditViewMock.PostSaved += null;
IEventRaiser postSavedRaiser =
LastCall.IgnoreArguments().GetEventRaiser();

mocks.ReplayAll();

new PostPresenter(postEditViewMock, blogDataServiceMock);
postSavedRaiser.Raise(postEditViewMock, EventArgs.Empty);

mocks.VerifyAll();
}

The error is:
Failures:
1) UnitTest.Tests.TestClass.SavePostNullException : An unexpected
exception type was thrown
Expected: System.NullReferenceException
but was: System.Reflection.TargetInvocationException


at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)

[0x00083] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:156
at System.Reflection.MethodBase.Invoke (System.Object obj,
System.Object[] parameters) [0x00000] in /home/esqueleto/myTrash/
MonoInstall/mcs/class/corlib/System.Reflection/MethodBase.cs:93
at System.Delegate.DynamicInvokeImpl (System.Object[] args)
[0x000b6] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System/Delegate.cs:370
at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args)
[0x00018] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System/MulticastDelegate.cs:71
at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000]
in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/System/
Delegate.cs:342
at Rhino.Mocks.Impl.EventRaiser.Raise (System.Object[] args)
[0x00000]
at UnitTest.Tests.TestClass.SavePostNullException () [0x00034] in /
home/esqueleto/Projects/MbUnitTest/UnitTest.Tests/TestClass.cs:65


at <0x00000> <unknown method>
at (wrapper managed-to-native)
System.Reflection.MonoMethod:InternalInvoke (object,object[])
at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00056] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:146


If I that the [ExpectedException(typeof(NullReferenceException))] tag
the error is:

Failures:
1) UnitTest.Tests.TestClass.SavePostNullException :
System.Reflection.TargetInvocationException : Exception has been
thrown by the target of an invocation.
----> System.NullReferenceException : Post object cannot be null


at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)

[0x00083] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:156
at System.Reflection.MethodBase.Invoke (System.Object obj,
System.Object[] parameters) [0x00000] in /home/esqueleto/myTrash/
MonoInstall/mcs/class/corlib/System.Reflection/MethodBase.cs:93
at System.Delegate.DynamicInvokeImpl (System.Object[] args)
[0x000b6] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System/Delegate.cs:370
at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args)
[0x00018] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System/MulticastDelegate.cs:71
at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000]
in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/System/
Delegate.cs:342
at Rhino.Mocks.Impl.EventRaiser.Raise (System.Object[] args)
[0x00000]
at UnitTest.Tests.TestClass.SavePostNullException () [0x00034] in /
home/esqueleto/Projects/MbUnitTest/UnitTest.Tests/TestClass.cs:65


at <0x00000> <unknown method>
at (wrapper managed-to-native)
System.Reflection.MonoMethod:InternalInvoke (object,object[])
at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00056] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:146

--NullReferenceException
at UnitTest.Controller.BlogDataService.SavePost
(UnitTest.Controller.Post post) [0x00026] in /home/esqueleto/Projects/
MbUnitTest/UnitTest.Controller/Service/BlogDataService.cs:22
at UnitTest.Controller.PostPresenter.Save () [0x00000] in /home/
esqueleto/Projects/MbUnitTest/UnitTest.Controller/Service/
PostPresenter.cs:30
at UnitTest.Controller.PostPresenter.onPostSaved (System.Object
sender, System.EventArgs e) [0x0000a] in /home/esqueleto/Projects/
MbUnitTest/UnitTest.Controller/Service/PostPresenter.cs:38


at <0x00000> <unknown method>
at (wrapper managed-to-native)
System.Reflection.MonoMethod:InternalInvoke (object,object[])
at System.Reflection.MonoMethod.Invoke (System.Object obj,
BindingFlags invokeAttr, System.Reflection.Binder binder,
System.Object[] parameters, System.Globalization.CultureInfo culture)
[0x00056] in /home/esqueleto/myTrash/MonoInstall/mcs/class/corlib/
System.Reflection/MonoMethod.cs:146


This is ok .. but the exception is not been tested. Maybe something is
wrong with the interfaces and the implementations?


tkx in advace
Paulo Aboim Pinto
Odivelas - Portugal

On Aug 7, 7:10 pm, "Ayende Rahien" <aye...@ayende.com> wrote:

> Looks like blogDataServiceMock.SavePost() is not a virtual method
>

Ayende Rahien

unread,
Aug 9, 2007, 1:14:40 AM8/9/07
to Rhino...@googlegroups.com
Can you create a small repro, so we can better help you?

> > > using (mockRepository.Record ())
> > > {
> > >    Expect.Call(mockService.MethodThatThrowsException()).Throw(new
> > > MyCustomException);
>
> > > }
>
> > > using (mockRepository.Playback ())
> > > {

Esqueleto

unread,
Aug 9, 2007, 4:15:53 PM8/9/07
to Rhino.Mocks
this is the example:

http://www.olimpocms.com/UsingRhinoMock.zip


tkx in advance
Paulo Aboim Pinto

Odivelas - Portugal

David Laribee

unread,
Aug 9, 2007, 10:52:10 PM8/9/07
to Rhino...@googlegroups.com
I can't see why you're testing for the exception this way. You can easily rephrase the test like so and get the same desired effect:

      [Test]
      [ExpectedException(typeof(NullReferenceException))]
      public void SavePostNullExceptionRedux()
      {
         BlogDataService dataService = new BlogDataService();
         dataService.SavePost(null);
      }

I'd do it like this keeping focused on the unit and then trusting an exception would be called from the presenter.

Also, if you're going to use the TearDown/VerifyAll trick I'd recommend this implementation:

      [TearDown]
      public void TearDown()
      {
         mocks.ReplayAll();
         mocks.VerifyAll();
      }

It's okay to have a redundant ReplayAll and desireable when you've got a fixture that mixes state tests w/ tests using rhino expectations. A second call to ReplayAll - correct me if I'm wrong - shouldn't hurt anything.

In the example you furnished one problem is that the exception is being raised in the BlogDataService which is a strict mock (CreateMock). That code will never get called, so you'll never get the exception.

I ended up mucking around with your test to see if I could get it to run. I got a TargetInvocationException. Looking in debugging I noticed that the InnerException was the NullReferenceException you trow in BlogDataService. Ayende, this may or may not be a bug?

      [Test]
      public void SavePostNullException()
      {
         IPostEditView viewMock = mocks.DynamicMock<IPostEditView>();
         BlogDataService serviceMock = mocks.DynamicMock<BlogDataService>();

         viewMock.PostSaved += null;
         LastCall.IgnoreArguments();
         IEventRaiser postSavedRaiser = LastCall.GetEventRaiser ();

         mocks.ReplayAll();

         PostPresenter presenter = new PostPresenter(viewMock, serviceMock);

         try
         {
            postSavedRaiser.Raise(viewMock, EventArgs.Empty);
         }
         catch (Exception ex) <- This is a
         {
            mocks.VerifyAll();
            throw;
         }
      }

Again, I'd strongly recommend you test directly against the unit and trust that from the presenter. If the presenter needs to cope with a NullReferenceException then you can pretty easily setup a test like so:

mockBlogService.SavePost(null);
LastCall.Throw(new NullReferenceException());



Hope this helps, good luck!


/ Dave

http://thebeelog.com


On 8/9/07, Esqueleto <esqu...@tusofona.com> wrote:

Esqueleto

unread,
Aug 11, 2007, 5:24:13 PM8/11/07
to Rhino.Mocks
tkx for the reply

Definitively was my problem to write Unit Tests. I thought that I need
all the time to run the test through the Presenter. Of course I can
run in every layers.

can you say what is the Replay State. I can't find anything about this
state.

tkx in advance
Paulo Aboim Pinto
Odivelas - Portugal

Reply all
Reply to author
Forward
0 new messages