如何在.Net Core中为测试设置EntryAssembly

6

我目前正在将一个项目及其测试项目从 .Net Framework 迁移到 .Net Core。

在 .Net Framework 中,我们曾经可以像这样设置测试的 EntryAssembly:

AppDomainManager manager = new AppDomainManager();
FieldInfo entryAssemblyfield = manager.GetType().GetField("m_entryAssembly", BindingFlags.Instance | BindingFlags.NonPublic);
entryAssemblyfield.SetValue(manager, assembly);

AppDomain domain = AppDomain.CurrentDomain;
FieldInfo domainManagerField = domain.GetType().GetField("_domainManager", BindingFlags.Instance | BindingFlags.NonPublic);
domainManagerField.SetValue(domain, manager);

摘自这里:https://dejanstojanovic.net/aspnet/2015/january/set-entry-assembly-in-unit-testing-methods/

由于在 .Net Core 中不再提供 AppDomainManager,我们该如何实现类似的功能,以便 Assembly.GetEntryAssembly(); 返回我想要的内容而不是测试项目程序集。


你尝试过 Assembly.GetCallingAssembly() 吗? - lukaszberwid
2
我认为你应该退一步,思考一下为什么要在测试代码中直接调用此方法。通过在代码中调用Assembly.GetEntryAssembly(),你将代码与这个静态方法耦合起来。如果你创建一个IAssemblyInfo接口(或类似的东西)并在代码中使用它会更好。对于实际执行,实现将调用Assembly.GetEntryAssembly(),但对于测试,你可以提供任何想要的值。 - ajz
@lukaszberwid,在我的情况下,Assembly.GetCallingAssembly()将无法工作,因为我在测试程序集和调用Assembly.GetEntryAssembly()之间经过了不同的程序集。如果您需要更多关于我的结构的信息,请让我知道,我可以更新我的问题。 - Simon Foley
@ajz,有趣的建议,我会尝试一下并告诉你它是否有效。 - Simon Foley
1
我同意使用接口,以便您可以为测试目的模拟类。 - Jonathan Busuttil
1个回答

6

这里有两种可能的解决方案:

1)像@ajz建议的那样,您可以创建一个带有GetEntryAssembly方法的接口,该方法返回 Assembly.GetEntryAssembly(),您可以将其模拟/设置为在测试中返回所需的任何内容。

2)您可以创建一个具有GetEntryAssembly Func的类,就像这样:

public static class AssemblyHelper
{
    public static Func<Assembly> GetEntryAssembly = () => Assembly.GetEntryAssembly();
}

在您的测试方法中,您可以通过重新为它分配一个内联函数来覆盖此行为:
AssemblyHelper.GetEntryAssembly = () => assembly;

我们选择第二种解决方案,只是因为我们曾在静态构造函数中调用 Assembly.GetEntryAssembly(),我认为在执行此操作之前无法模拟对象并将其设置为字段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接