简体   繁体   English

如何在 STA 线程中运行 NUnit 测试?

[英]How to run NUnit test in STA thread?

We are in the process of porting a WPF app to .NET Core 3, preview 5. Some NUnit tests need to run in STA threads.我们正在将 WPF 应用程序移植到 .NET Core 3,预览版 5。一些 NUnit 测试需要在 STA 线程中运行。 How can this be done?如何才能做到这一点?

None of the attributes like [STAThread], [RequiresSTA], ... work. [STAThread]、[RequiresSTA] 等属性都不起作用。 This also doesn't work: [assembly: RequiresThread(ApartmentState.STA)]这也不起作用:[程序集:RequiresThread(ApartmentState.STA)]

The Apparent namespace does not seem to be exposed in .NET Core 3. .NET Core 3 中似乎没有公开表观命名空间。

Has anyone done this?有人做过吗?

ApartmentAttribute was first enabled for .NET Standard 2.0 in NUnit 3.12. ApartmentAttribute首次在 NUnit 3.12 中为 .NET Standard 2.0 启用。

First update your version of the NUnit framework, then use [Apartment(ApartmentState.STA)] .首先更新您的 NUnit 框架版本,然后使用[Apartment(ApartmentState.STA)]

In order to use STA in WPF unit testing in .Net Core 3 you need to add extension method attribute.为了在 .Net Core 3 中的 WPF 单元测试中使用 STA,您需要添加扩展方法属性。 Add this class添加这个类

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) };
    }
}

And then use it as然后将其用作

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

    //Act


    // Assert

}

I recently ported my application to .Net 6 and could not get this to work.我最近将我的应用程序移植到 .Net 6 并且无法使其正常工作。

However - implementing IWrapTestMethod seems to work:但是 - 实施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!");
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM