如何对用 C# 编写的 Word AddIn 进行单元测试

软件测试 C# 视觉工作室 办公室
2022-01-12 20:40:16

我需要有关此主题的端到端指导。

这是一个场景:我有一个用 C# 编写的 Word AddIn,其中我与 Excel 进行了一些互操作交互。我需要对其进行单元测试。

如何?

关于该主题没有可用的指导,除了这个:http ://clear-lines.com/blog/post/unit-testing-vsto-projects.aspx

谢谢德拉甘

3个回答

几乎所有关于单元测试的问题的答案都是“从依赖中解耦”。

重构您的代码以将逻辑(您想要测试的)与与 Excel 的交互分离。

请记住,单元测试应该回答“我正在编写的代码是否按照我的意图执行”而不是“我的程序是否正常工作”的问题——这是针对集成测试的。

我还没有进行过此类测试,我建议您研究如何编写利用加载项功能测试其功能的 Office 宏。您应该能够将 vba 命令按钮添加到电子表格或文档或运行测试的单词工具栏。

我假设当您在 VSTO 中进行测试和添加时,您对 excel 和 word API 有很好的工作知识,因为这是必需的。

OfficeAddin/ThisAddIn.cs

using System;
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using System.Runtime.InteropServices;

namespace OfficeAddIn
{
    public partial class ThisAddIn
    {
        public static string OfficeAddress = @"Path\To\Word.doc";
        public void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            CallflowTester.ThisAddIn_Startup(sender, e);
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        private AddinUtilities utilities;
        protected override object RequestComAddInAutomationService()
        {
            if (utilities == null)
                utilities = new AddinUtilities();
            return utilities;
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion

    }
}

OfficeAddin/AddinUtilities.cs

using System;
using System.Runtime.InteropServices;
using Word = Microsoft.Office.Interop.Word;

namespace OfficeAddIn
{
    [ComVisible(true)]
    [Guid("274069A2-1895-4B18-BFEA-125FE2D89D02")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IAddInUtilities
    {
        // Setting Up
        void runSetupFunction(ref Word.Application a);

        // Functional Test
        int runAddInFunction(int page, int item);
    }

    [ComVisible(true)]
    [Guid("A18CDCA6-F138-44D4-8BD9-3EC68FE8B546")]
    [ClassInterface(ClassInterfaceType.None)]
    public class AddinUtilities :
    StandardOleMarshalObject,
    IAddInUtilities
    {
        // Setting Up
        public void runSetupFunction(ref Word.Application a) => yourSetupFunction(a);

        // Functional Test
        public int runAddInFunction(int page, int item) => yourAddInFunction(page, item);
    }
}

OfficeAddinTests/ThisAddInTests.cs

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;

namespace OfficeAddIn_Tests
{
    [TestClass]
    public class AudioTTSTests
    {
        private static string wordAddress = @"Address/To/Word.doc";

        #region Test Setup

        private static Word.Application word = null;
        public static Word.Document wdoc = null;
        static ECCO_Callflow_Tools.IAddInUtilities utilities = null;

        [ClassInitialize()]
        public static void This_AddIn_Initialize(TestContext t)
        {
            word = new Word.Application();
        }

        public static void SetupDocuments()
        {
            try {
                object addInName = "TheNameOfYOurAddin";
                wdoc = word.Documents.Open(wordAddress);
                Office.COMAddIn addIn = word.COMAddIns.Item(ref addInName);

                while (utilities == null)
                {
                    utilities = (OfficeAddIn.IAddInUtilities)addIn.Object;
                    System.Threading.Thread.Sleep(100);
                }
                utilities.runSetupFunction();
            }
            catch (Exception ex) {
                wdoc?.Close();
                word.Quit();
                word = null;
                utilities = null;
                GC.Collect();
                throw ex;
            }
        }

        [TestCleanup()]
        public void TestCleanup()
        {
            if (word != null)
            {
                word.Quit();
                word = null;
            }
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        #endregion

        [TestMethod()]
        public void AudioTTSTests_Setup()
        {
            SetupDocuments();
            utilities.runAddInFunction();
        }
    }
}

这里有一些开始的链接。您需要了解如何在此处从其他应用程序调用代码 https://msdn.microsoft.com/en-us/library/bb608621.aspx

如果您尝试从外部应用程序调用,则会出现一些错误,因此我发现此链接很有帮助 https://stackoverflow.com/questions/10875278/vsto-add-ins-comaddins-and-requestcomaddinautomationservice