T4 的 this.Host 作为 IServiceProvider 的可测试替代品

Testable substitute for T4's this.Host as IServiceProvider

我们创建了一个 class 以在采用 this.Host 作为参数的 T4 模板中使用。它通过像这样将 this.Host 转换为 IServiceProvider 来实现...

var serviceProvider = this.Host as IServiceProvider;

...然后将 serviceProvider 传递到 class.

这允许将代码封装在 T4 模板中,使它们更容易被更多的初级开发人员使用。当我们尝试为此 class.

创建测试时,问题就来了

IServiceProvider,作为一个接口,是非常可测试的,我们可以通过为接口创建一个替代品来对它进行单元测试,但是替代品没有任何从 [= 派生的内在逻辑12=]。

通过 class 测试来自测试的任何模板功能不会提供任何有意义的好处。在 class 上完成的唯一有意义的测试必须通过特定模板的手动测试来完成。我想改变这个。

有人知道从测试中传递有意义的 T4 this.Host 值的好方法吗?

this.Host 表示您正在处理的 Visual Studio 个实例。您可以通过以下代码获取活动的Vs实例

        var dte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.14.0"); 
        IServiceProvider serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte.DTE); 

"VisualStudio.DTE.14.0" 指的是一个 Vs 2015 项目,我正在尝试代码是否正常工作。

请注意,如果打开了多个 Vs 实例,代码将 select 随机打开其中一个。您将需要一些额外的工作来确保获得正确的 Vs 实例。

如果您正在尝试编写单元测试,那么最好使用 Mock 框架来隔离您的代码,例如 Moq。请检查 Moq quick start page