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

10

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

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

在.NET Core 3中似乎没有暴露Apparent命名空间。

有人做过这个吗?


“Apparent” 命名空间在 .NET Core 3 中似乎没有被公开。-- 当然有。请参考 https://learn.microsoft.com/en-us/dotnet/api/system.stathreadattribute?view=netcore-3.0 - Daniel Mann
@DanielMann 是的,你当然是正确的。我应该说“在NUnit 3.11的netstandard2.0配置中,似乎没有暴露公寓属性”。我混淆了,我的错。 - Sven
3个回答

9

ApartmentAttribute在NUnit 3.12中首次支持.NET Standard 2.0。

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


一个更详细的答案 https://dev59.com/v3E95IYBdhLWcg3wJKl_#35587531 - marbel82

1
为了在 .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

}

0
最近我将我的应用程序迁移到了.Net 6,但无法使其正常工作。
然而,实现似乎是有效的:
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!");
        }
    }
}

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