Mocking a function to return an actual COM Object fails

0 votes

I'm testing an application that interacts with Microsoft Excel.  When using WhenCalled on a mock object that I'm returning an Excel Range from, the calls fails.  The exact failure depends upon whether I use WillReturn (TypeMockException: Can not fake methods defined in mscorlib, try faking the defining type) or DoInstead (TypeMockException: Cannot return System.__ComObject value from method that returns Microsoft.Office.Interop.Excel.Range).  I'm currently using TypeMock 8.1.1.11.  This test previously worked in 6.0.8.

Essentially, I have an interface like:

public interface ISomeInterface
{
    Microsoft.Office.Interop.Excel.Range GetRange();
}

And my test code does:

var mockObject = Isolate.Fake.Instance<ISomeInterface>();
Microsoft.Office.Interop.Excel.Range range = excelWorksheet.UsedRange;
Isolate.WhenCalled(() => mockObject.GetRange()).WillReturn(range);
// or
Isolate.WhenCalled(() => mockObject.GetRange()).DoInstead(context => range);

When using WillReturn, the TypeMockException is thrown when executing the mocking statement.  When using DoInstead, the TypeMockException is thrown when the test code actually executes the GetRange method.

Is there some way to actually return the COM object (the Excel Range)?

Thanks,

-Kevin

asked Apr 8, 2016 by kevinms99 (1,140 points)

2 Answers

0 votes
Hi Kevin,

I didn't manage to reproduce this, it seems to be running fine on my machine.

Can you please try running this test with Isolator 8.3 (the latest version on our site)

Let me know if it reproduces.

 

Alex Galin | Support Team

answered Apr 12, 2016 by alex (17,890 points)
8.3 gives me the same behavior.  I guess there's either another trigger that causes the behavior that I'm seeing or I'm misunderstanding the error.

I'll try to narrow down the actual testcase I have.

I didn't have any issue reproducing this in a fairly simple testcase:

using System;
using Microsoft.Office.Interop.Excel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TypeMock.ArrangeActAssert;

namespace TypeMock8._1CannotReturnCOMObject
{
    [TestClass]
    [Isolated]
    public class UnitTest1
    {
        public interface IRangeGetter
        {
            Range GetRange();
        }
        [TestMethod]
        public void TestMethod1()
        {
            RunExcelTest(
                (range, getter) =>
                {
                    // Error here -> TypeMockException: *** Can not fake methods defined in mscorlib, try faking the defining type
                    Isolate.WhenCalled(() => getter.GetRange()).WillReturn(range);

                    Range actual = getter.GetRange();

                    Assert.AreEqual(range, actual);
                });
        }

        [TestMethod]
        public void TestMethod2()
        {
            RunExcelTest(
                (range, getter) =>
                {
                    Isolate.WhenCalled(() => getter.GetRange()).DoInstead(ctx => range);

                    // Error here -> TypeMockException: *** Cannot return System.__ComObject value from method that returns Microsoft.Office.Interop.Excel.Range
                    Range actual = getter.GetRange();

                    Assert.AreEqual(range, actual);
                });
        }

        private static void RunExcelTest(Action<Range, IRangeGetter> testToRun)
        {
            Application excel = new ApplicationClass();
            try
            {
                Workbook wb = excel.Workbooks.Add();
                Worksheet ws = (Worksheet)wb.Worksheets.Add();
                Range range = ws.Range["A1"];
                IRangeGetter getter = Isolate.Fake.Instance<IRangeGetter>();

                testToRun(range, getter);
            }
            finally
            {
                // Shut down Excel
                foreach (Workbook workbook in excel.Workbooks)
                {
                    workbook.Close(SaveChanges: false);
                }
                excel.Quit();
            }
        }
    }
}

I'm using Excel from Office 2010.  My test project included a reference to Microsoft.Office.Interop.Excel and was built targeting framework 4.0 with the CPU target set to x86.  I don't know if those last two matter, but that matches our product's build environment.

it reproduced with your example.

 

Alex Galin | Support Team

0 votes
This issue is fixed in version 8.4.0
answered Jun 14, 2016 by eva (1,580 points)
...