chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi,

I have the following code, which trys to test an exceptioin being thrown and I came across some strange behaviour.
namespace boo
{
   internal Class foo
   {
      private void ParseConsistsTag (string line)
           {
                  string[] parts = line.Replace (" ", String.Empty).Split (':');

              if (parts.Length != 3)
                      throw new MaterialInvalidArgumentException (String.Format ("The line <0> was illegal. It should have had the segments 'ID:Name:Percentage'.", line));

         // ....     
        }
}


namespace Exceptions
{
   [Serializable]
       public class MaterialInvalidArgumentException : Exception
       {
           public MaterialInvalidArgumentException () { }

           public MaterialInvalidArgumentException (string message) : base (message) { }
   
           public MaterialInvalidArgumentException (string message, Exception inner) : base (message, inner) { }

           protected MaterialInvalidArgumentException (SerializationInfo info, StreamingContext context) : base (info, context) { }
       }
}

namespace Test.boo
{
   [Test, Isolated]
   [ExpectedException(typeof(MaterialInvalidArgumentException))]
   public void Test.foo
   {
      string[] lines = new[] { "Additiv05 : 10", " : Input09 : 85", ": Additiv13 : 5" };

      foo = new foo();

      Isolate.NonPublic.WhenCalled(txt,"ParseConsistsTag").WillThrow (new MaterialInvalidArgumentException());

      foreach (var line in lines)
         Isolate.Invoke.Methode (foo, "ParseConsistsTag", line);

      // ...
   }
}

Ultimately this results in 3 thrown exceptions but the messages got lost somehow or at least it is not displayed. But more important the test fails with 3 exceptions being thrown. Which is wrong since the parameters handed in are correct on call 2 & 3. Since I am testing for exceptions being thrown the test should fail but tell me that it has one exception catched and twice the code does not meet the expectation.

If however I do the following everything works fine and I have the messages and the test completes successfully.

namespace Test.boo
{
        [Test, Isolated]
        public void ParseConsistsTag_InCorrectConsistsMaterialLine_ThrowsMaterialInvalidArgumentException ()
        {
            string[] lines = new[] { "Additiv05 : 10", " : Input09 : 85", ": Additiv13 : 5" };

            foo txt = new foo ();

            foreach (string line in lines)
                try
                {
                    Isolate.Invoke.Method (foo, "ParseConsistsTag", line);
                }
                catch (MaterialInvalidArgumentException ex)
                {
                    // Info: Should be a call to the logger!
                    Console.WriteLine ("ERROR: {0}", ex.Message);
                }

            // ...

            }
        }
}


What am I doing wrong in the first place or do I misunderstand here something?

Thank's for any hint or help!
Peter
asked by mph (6k points)

2 Answers

0 votes
Hi Peter,

The first test will not throw the exception three times since the first time the method ParseConsistsTag gets called the exception is thrown and the test ends.
Note that when you use the API:
Isolate.NonPublic.WhenCalled(foo, "ParseConsistsTag").WillThrow(new MaterialInvalidArgumentException());
The method body will not execute! When the method get called the exception will be thrown immediately.
This also means that you have to set the exception message when you set the behavior:
Isolate.NonPublic.WhenCalled(foo, "ParseConsistsTag").WillThrow(new MaterialInvalidArgumentException("Some error message"));
The second test is different. You are actually execution the method body so you get the real logic of the method.

:idea: There is one line missing in the second test - You should make sure that if the exception is NOT thrown the test will fail.
Try this:
try
{
    Isolate.Invoke.Method(txt, "ParseConsistsTag", line);
    Assert.Fail("Method ParseConsistsTag should have thrown an exception"); // <== Add this line
}
catch (MaterialInvalidArgumentException ex)
{
    // Info: Should be a call to the logger!
    Console.WriteLine("ERROR: {0}", ex.Message);
}


Hope it helps.
answered by ohad (35.4k points)
0 votes
Hi,

Thank's for the clearification. No I understand it much better.

And yes, it helps quite a bit!

Peter
answered by mph (6k points)
...