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
0 votes
I ran into trouble with Unexpected VerificationException:

Here's the production code:
   public class EmailNotificationOperation
    {
        public string FromWho
        { get; set; }
        public List<string> ToWho
        { get; set; }

        public string ToWhoStr
        {
            get
            {
                string str = string.Empty;
                for (int i = 0; i < ToWho.Count; i++)
                {
                    str += ToWho[i];
                    if (i != ToWho.Count - 1)
                        str += ",";
                }
                return str;
            }
        }
        public string EmailBody
        { get; set; }
        public string EmailSubject
        { get; set; }
        public string AttachedFile
        { get;  set; }


        public void SendEmail()
        {
            //try
            //{
                SmtpClient sMail = new SmtpClient("localhost");//exchange or smtp server goes here.
                sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
                MailMessage mailMessage=new MailMessage(FromWho, ToWhoStr, EmailSubject, EmailBody);
                mailMessage.Attachments.Add(new Attachment(AttachedFile));
                sMail.Send(mailMessage);
            //}
            //catch (Exception ex)
            //{
            //    return false;
            //}
            //return true;
        }

        public EmailNotificationOperation()
        {
            FromWho = string.Empty;
            EmailSubject = string.Empty;
            EmailBody = string.Empty;
            AttachedFile = string.Empty;
        }

    }


Here's the test code:
        [Test, Isolated]
        public void DoubleTake2()
        {
  
            SmtpClient smtpFake = Isolate.Fake.Instance<SmtpClient>(Members.ReturnRecursiveFakes);
            Isolate.Swap.NextInstance<SmtpClient>().With(smtpFake);
            EmailNotificationOperation op = new EmailNotificationOperation();
            op.FromWho = "a";
            op.ToWho = new List<string> { "b" };
            op.EmailBody = "c";
            op.EmailSubject = "d";
            op.AttachedFile = "e";
            MailMessage mailMessage = Isolate.Fake.Instance<MailMessage>(Members.MustSpecifyReturnValues);
            Isolate.Swap.NextInstance<MailMessage>().With(mailMessage);
           op.SendEmail();
            Isolate.Verify.WasCalledWithAnyArguments(() => smtpFake.Send(mailMessage));
           
        }


Here's the exception:
failed: TypeMock.VerifyException : 
TypeMock Verification: Unexpected Call to System.Net.Mail.MailMessage.get_Attachments()
   at System.Net.Mail.MailMessage.get_Attachments()


There is no reason of this unexpectation, isn't it?
________
Utg special universal tactical holster
asked by nsoonhui (59.1k points)

6 Answers

0 votes
Hi Soon Hui,

You're getting the verify exception because of the fact that the MailMessage fake is created with MustSpecify parameter and as such calling it's property (Attachments) cause a verify exception.
The other problem in the test is that currently Isolator does not support faking of objects defined in MSCorLib and because AttachmentCollection.Add cannot be faked.
To solve the second problem I suggest you create a method that adds a new attachment to the MailMessage object and fake this method instead.
answered by dhelper (11.9k points)
0 votes
Hi Soon Hui,

You're getting the verify exception because of the fact that the MailMessage fake is created with MustSpecify parameter and as such calling it's property (Attachments) cause a verify exception.
The other problem in the test is that currently Isolator does not support faking of objects defined in MSCorLib and because AttachmentCollection.Add cannot be faked.
To solve the second problem I suggest you create a method that adds a new attachment to the MailMessage object and fake this method instead.


Ah, OK. My bad. I intended to put in ReturnRecursiveFakes but I must have mistyped in MustSpecifyReturnValues instead. Thanks for your help!
________
Bondage fetish
answered by nsoonhui (59.1k points)
0 votes
Hi, I ran into problem again when trying to mock away the Add statement. Using WhenCall on MailMessage.Attachment.Add gives me a null referenceexception:


        [Test, Isolated]
        public void DoubleTake2()
        {
          
            MailMessage mailMessage = Isolate.Fake.Instance<MailMessage>(Members.ReturnRecursiveFakes);
            Assert.IsNotNull(mailMessage.Attachments);
            Isolate.WhenCalled(()=>mailMessage.Attachments.Add(null)).IgnoreCall();

           
        }


The exception is
failed: System.NullReferenceException : Object reference not set to an instance of an object.
   at System.Collections.ObjectModel.Collection`1.Add(T item)
   C:developmentReleaseScriptInstantDllUpdateSourceDllSendApppTestControllersAnotherTest.cs(133,0): at DllSendApppTest.Controllers.AnotherTest.<>c__DisplayClass7.<DoubleTake2>b__6()


Note that although AttachmentCollection extends from Collection<Attachment>, which is in mscorelib.dll, but Typemock shouldn't have problem in mocking AttachmentCollection because it's located in System.Net.Mail.dll. If it had problem it should fail at

 Assert.IsNotNull(mailMessage.Attachments);

________
Kitchen Measures
answered by nsoonhui (59.1k points)
0 votes
The problem with AttachmentCollection.Add is that part of its implementation is in MsCorLib and currently Isolator cannot fake it.
As I wrote above the only solution out of this problem is to create a simple method in your code:
private void AddNewAttachment(Attachment attachment)
{
    mailMessage.Attachments.Add(attachment); 
}

And fake this method call instead.
answered by dhelper (11.9k points)
0 votes
The problem with AttachmentCollection.Add is that part of its implementation is in MsCorLib and currently Isolator cannot fake it.
As I wrote above the only solution out of this problem is to create a simple method in your code:
private void AddNewAttachment(Attachment attachment)
{
    mailMessage.Attachments.Add(attachment); 
}

And fake this method call instead.


I see, OK.

But even so, maybe you can just override the Add implementation in MSCorlib since the rest of the code of Attachment is in System.Net.dll.

Is it possible?
________
Pornstars celeste
answered by nsoonhui (59.1k points)
0 votes
Unfortunatly it isn't possible to fake calls to Add (yet)
answered by dhelper (11.9k points)
...