MOQ - verify exception was thrown

前端 未结 7 1869
暗喜
暗喜 2021-01-07 16:22

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          


        
相关标签:
7条回答
  • 2021-01-07 16:49

    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.

    0 讨论(0)
  • 2021-01-07 16:57

    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());
    
    0 讨论(0)
  • 2021-01-07 16:59

    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.

    0 讨论(0)
  • 2021-01-07 17:04

    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).

    0 讨论(0)
  • 2021-01-07 17:05

    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.ShouldThrow<SomeException>();
    

    http://fluentassertions.codeplex.com/documentation

    http://www.nunit.org/index.php?p=exceptionAsserts&r=2.6.2

    0 讨论(0)
  • 2021-01-07 17:08

    You can test that an Exception is thrown using NUnit Asserts:

    Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>());
    
    0 讨论(0)
提交回复
热议问题