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'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 by kevinms99 (4.4k points)

1 Answer

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.
answered by alex (17k 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.
...