How do I mock Outlook.MailItem with multiple Attachments using NSubstitute?

Viewed 102

I'm trying to unit test a static function that accepts an Outlook.MailItem argument type:

public static bool GetMailAndDoSomething(Outlook.MailItem mailitem)

Here is what I have so far in my test function:

using Outlook = Microsoft.Office.Interop.Outlook;
...
public void TestGetMailAndDoSomething()
{
    Outlook.MailItem mailItem = Substitute.For<Outlook.MailItem>();

    Outlook.Attachments attachments = Substitute.For<Outlook.Attachments>();
    attachments.Add(Substitute.For<Outlook.Attachment>());
    attachments.Add(Substitute.For<Outlook.Attachment>());
    attachments.Add(Substitute.For<Outlook.Attachment>());
    attachments.Add(Substitute.For<Outlook.Attachment>());

    mailItem.Attachments.GetEnumerator().Returns(attachments.GetEnumerator());

    Assert.True(Misc.GetMailAndDoSomething(mailItem));
}

Inside the GetMailAndDoSomething function, there is a piece of code that I want to test

foreach (Outlook.Attachment attachment in mailItem.Attachments)
{
       //do someting
}

However, the test program never reaches //do something because mailItem.Attachments always seem empty. This is what I see when my IDE breaks at the foreach line.

enter image description here

What do I need to fix in the test function so that the test program will reach //do something in the targeted function?

1 Answers

You are trying to perform implementations on an interface.

Attachments is derive from IEnumerable

[System.Runtime.InteropServices.Guid("0006303C-0000-0000-C000-000000000046")]
public interface Attachments : System.Collections.IEnumerable

Consider using an actual list as a memory store and then setting up the mock to return that

var list = new List<Outlook.Attachment>();
list.Add(Substitute.For<Outlook.Attachment>());
list.Add(Substitute.For<Outlook.Attachment>());
list.Add(Substitute.For<Outlook.Attachment>());
list.Add(Substitute.For<Outlook.Attachment>());

Outlook.Attachments attachments = Substitute.For<Outlook.Attachments>();
attachments.GetEnumerator().Returns(list.GetEnumerator());

Outlook.MailItem mailItem = Substitute.For<Outlook.MailItem>();
mailItem.Attachments.Returns(attachments);

//...
Related