【问题标题】:How to run NUnit test in STA thread?如何在 STA 线程中运行 NUnit 测试?
【发布时间】:2019-06-12 16:56:20
【问题描述】:

我们正在将 WPF 应用程序移植到 .NET Core 3,预览版 5。 一些 NUnit 测试需要在 STA 线程中运行。如何做到这一点?

[STAThread]、[RequiresSTA]、...等属性都不起作用。 这也不起作用:[程序集:RequiresThread(ApartmentState.STA)]

在 .NET Core 3 中似乎没有公开表观命名空间。

有人做过吗?

【问题讨论】:

  • 在 .NET Core 3 中似乎没有公开明显的命名空间。。 - 是的。 docs.microsoft.com/en-us/dotnet/api/…
  • @DanielMann 是的,你当然是对的。我应该说“对于 netstandard2.0 配置,NUnit 3.11 中似乎没有公开 Apartment 属性”。我很困惑,我的错。

标签: c# .net-core nunit sta


【解决方案1】:

ApartmentAttribute 首次在 NUnit 3.12 中为 .NET Standard 2.0 启用。

首先更新您的 NUnit 框架版本,然后使用 [Apartment(ApartmentState.STA)]

【讨论】:

【解决方案2】:

为了在 .Net Core 3 的 WPF 单元测试中使用 STA,您需要添加扩展方法属性。 添加这个类

public class STATestMethodAttribute : TestMethodAttribute
{
    public override TestResult[] Execute(ITestMethod testMethod)
    {
        if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
            return Invoke(testMethod);

        TestResult[] result = null;
        var thread = new Thread(() => result = Invoke(testMethod));
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
        return result;
    }

    private TestResult[] Invoke(ITestMethod testMethod)
    {
        return new[] { testMethod.Invoke(null) };
    }
}

然后把它当作

[STATestMethod]
public void TestA()
{
    // Arrange  
    var userControlA = new UserControl();

    //Act


    // Assert

}

【讨论】:

    【解决方案3】:

    我最近将我的应用程序移植到 .Net 6,但无法使其正常工作。

    但是 - 实施 IWrapTestMethod 似乎有效:

    using NUnit.Framework;
    using NUnit.Framework.Interfaces;
    using NUnit.Framework.Internal;
    using NUnit.Framework.Internal.Commands;
    
    namespace NunitExtensions;
    
    /// <summary>
    /// This attribute forces the test to execute in an STA Thread.
    /// Needed for UI testing.
    /// The NUnit <see cref="NUnit.Framework.ApartmentAttribute"/> does not seem to work on .Net 6....
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, Inherited = false)]
    public class UITestAttribute : NUnitAttribute, IWrapTestMethod
    {
        public TestCommand Wrap(TestCommand command)
        {
            return Thread.CurrentThread.GetApartmentState() == ApartmentState.STA 
                ? command 
                : new StaTestCommand(command);
        }
    
        private class StaTestCommand : TestCommand
        {
            private readonly TestCommand _command;
    
            public StaTestCommand(TestCommand command) : base(command.Test)
            {
                _command = command;
            }
    
            public override TestResult Execute(TestExecutionContext context)
            {
                TestResult? result = null;
                var thread = new Thread(() => result = _command.Execute(context));
                thread.SetApartmentState(ApartmentState.STA);
                thread.Start();
                thread.Join();
                return result ?? throw new Exception("Failed to run test in STA!");
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 2011-01-24
      • 1970-01-01
      相关资源
      最近更新 更多