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。
我们创建了一个 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。