微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么这个 Fixture 不止一次运行它的构造函数?

如何解决为什么这个 Fixture 不止一次运行它的构造函数?

为什么以下 xUnit 测试没有通过。 ProgramFixture 构造函数运行了 3 次,但我只想为所有测试保留相同的实例,因此 Count 属性应该是: 1,2,3 in a sequence。为什么它给我: 1,1,1 因为它为每个 ProgramFixture 测试实例化一个新的 InlineData

程序:

namespace UnitTest
{
    public sealed class Program
    {
        public int Count { get; set; }

        public void IncrementCount()
        {
            ++this.Count;
        }

        // Mandatory Main method for the entry point.
        public static void Main() { }
    }
}

xUnit:

using System;
using System.Diagnostics;
using Xunit;

namespace UnitTestTests
{
    public sealed class ProgramFixture : Idisposable
    {
        private bool disposed = false;

        public UnitTest.Program Program { get; }

        public ProgramFixture()
        {
            this.Program = new();
            Debug.WriteLine("################## ProgramFixture constructor runned.");
        }

        public void dispose()
        {
            dispose(true);
            GC.SuppressFinalize(this);
        }

        private void dispose(bool disposing)
        {
            if (this.disposed)
                return;

            if (disposing)
            {
                Debug.WriteLine("################## ProgramFixture disposed.");
            }

            this.disposed = true;
        }
    }

    public sealed class UnitTest1 : IClassFixture<ProgramFixture>
    {
        private readonly ProgramFixture programFixture;

        public UnitTest1(ProgramFixture programFixture)
        {
            this.programFixture = programFixture;
        }

        [Theory]
        [InlineData(1)]
        [InlineData(2)]
        [InlineData(3)]
        public void Test1(int expectedCount)
        {
            this.programFixture.Program.IncrementCount();

            Assert.Equal(expectedCount,this.programFixture.Program.Count);
        }
    }
}

错误

enter image description here

调试时:

enter image description here

我使用的是 Visual Studio Community 2019 16.10.3

这是 Visual Studio 上的错误还是某些机器特定的错误

编辑

我的项目文件

程序:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

xUnit:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <packagereference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
    <packagereference Include="xunit" Version="2.4.1" />
    <packagereference Include="xunit.runner.visualstudio" Version="2.4.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </packagereference>
    <packagereference Include="coverlet.collector" Version="3.0.2">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </packagereference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\UnitTest\UnitTest.csproj" />
  </ItemGroup>

</Project>

编辑 2

我注意到我已经反转了它的参数的 Assert.Equal 方法签名顺序,所以我将 Assert.Equal(this.programFixture.Program.Count,expectedCount) 编辑为 Assert.Equal(expectedCount,this.programFixture.Program.Count),因此在第一个错误屏幕截图中,预期值和实际值显示在右侧面板与此不同,但问题仍然相同。

enter image description here

解决方法

错误已确认,错误报告已于 https://github.com/xunit/xunit/issues 填写。不幸的是,我被迫使用不太惯用的单元测试方法,但至少它健壮、可靠并且工作时没有提到的任何问题,并且适合除 Count 之外的另一个对象属性以保持其相同状态在这个单一的测试环境中:

程序:

using System;
using System.Diagnostics;

namespace UnitTest
{
    public sealed class Program : IDisposable
    {
        public int Count { get; set; }

        private bool disposed = false;

        public Program()
        {
            Debug.WriteLine("################## Program constructor runned.");
        }

        public void IncrementCount()
        {
            ++this.Count;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (this.disposed)
                return;

            if (disposing)
            {
                Debug.WriteLine("################## Program disposed.");
            }

            this.disposed = true;
        }

        // Mandatory Main method for the entry point.
        public static void Main() { }
    }
}

xUnit:

using Xunit;

namespace UnitTestTests
{
    public sealed class UnitTest1
    {
        [Fact]
        public void Test1()
        {
            using (var program = new UnitTest.Program())
            {
                int[] expectedCounts = { 1,2,3 };

                foreach (var expectedCount in expectedCounts)
                {
                    program.IncrementCount();
                    Assert.Equal(expectedCount,program.Count);
                }
            }
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。