【问题标题】:Flurl & HttpTest: Unit tests fail when Run All, but pass when run individuallyFlurl & HttpTest:单元测试在全部运行时失败,但在单独运行时通过
【发布时间】:2016-11-02 04:40:48
【问题描述】:

更新: HttpTest 不是线程安全的,根据项目的 GitHub issue。在问题解决之前,使用HttpTest 的测试无法并行运行。

我有一对使用 Flurl 和 xUnit 的非常奇怪的测试,当在 VS 测试资源管理器中运行全部时,它会失败,但如果单独运行,则会通过。我终其一生都看不到这 2 个甚至彼此相关的任何地方,但它们确实如此。

我已将它们从我的项目中提取到一个新项目中,但问题仍然存在。我将它们捆绑到 7z 中,供任何有兴趣将其加载到 VS 的人使用,但完整的代码如下。

Project.Commons

GetApi1:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;

namespace Project.Commons
{
    public class GetApi1
    {

        public async Task<string> ExecuteAsync(string token)
        {
            string apikeyKeyname = "token";

            dynamic response = await "http://www.api.com"
                .SetQueryParams(new { token = token })
                .GetJsonAsync();

            string receivedApiKey = ((IDictionary<string, object>)response)[apikeyKeyname].ToString();

            return receivedApiKey;
        }
    }
}

GetApi2:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;

namespace Project.Commons
{
    public class GetApi2
    {
        public async Task<IList<string>> ExecuteAsync()
        {
            var responses = await "http://www.api.com"
                .GetJsonAsync<List<string>>();

            var result = new List<string>();

            foreach (var response in responses)
            {
                result.Add("refined stuff");
            }

            return result;
        }
    }
}

Project.Tests

单元测试1:

using Project.Commons;

namespace Project.Tests
{
    public class UnitTest1
    {
        private ITestOutputHelper output;
        public UnitTest1(ITestOutputHelper output)
        {
            this.output = output;
        }

        [Fact]
        public async Task ShouldBeAbleToGetApiKeyFromToken()
        {
            // Arrange
            using (var httpTest = new HttpTest())
            {
                var jsonResponse = new { token = "abcdef" };
                string expectedApiKey = "abcdef";
                httpTest.RespondWithJson(jsonResponse);
                var api = new GetApi1();

                // Act
                var receivedApiKey = await api.ExecuteAsync("mockToken");
                output.WriteLine("Received apikey = " + receivedApiKey);

                // Assert
                Assert.Equal(expectedApiKey, receivedApiKey);
            }
        }
    }
}

单元测试2

using Flurl.Http.Testing;
using Project.Commons;
using Xunit;
using Xunit.Abstractions;

namespace Project.Tests
{
    public class UnitTest2
    {


        #region Mock API JSON Response
        private IList<string> mockResponse = new List<string>()
        {
            "raw stuff", "raw stuff", "raw stuff"
        };
        #endregion

        #region Expected Result
        private IList<string> expectedResult = new List<string>()
        {
            "refined stuff", "refined stuff", "refined stuff"
        };
        #endregion

        [Fact]
        public async Task CanGetProjectsByWeek()
        {
            // Arrange
            using (var httpTest = new HttpTest())
            {
                httpTest.RespondWithJson(mockResponse);

                // Act
                var api = new GetApi2();
                var actualResult = await api.ExecuteAsync();

                // Assert
                Assert.Equal(expectedResult,actualResult);
            }
        }
    }
}

【问题讨论】:

  • 没有经常使用 xunit - 测试是否以并行运行?因为查看 HttpTest 类,它看起来并不适合从多个线程中使用。
  • 是的,测试是并行运行的。那么...有没有 HttpTest 的替代品或使其异步友好的方法?
  • 我尝试从测试中删除所有 async 关键字,而不是 await api.ExecuteAsync() 我尝试了 ExecuteAsync().Result。来自同一测试类的测试将通过,但来自其他类的测试将失败。似乎这些类仍在异步运行。
  • 快速浏览一下 xunit,它似乎默认在不同的类中并行运行单元测试。杀死我们的是并行性,而不是async
  • 我没有找到快速解决此问题的方法。 Flurl 似乎使用全局配置系统。 HttpTest 通过将配置重写为关于“它”来工作。然后在处理“它”时将所有内容重置为默认值 - 如果有多个“它”,这将不起作用。

标签: c# unit-testing xunit flurl


【解决方案1】:

cmets 是正确的 - 缺乏线程安全是 HttpTest 的一个已知限制。它是logged,正在调查中。与几年前创建并行测试时相比,今天的并行测试更为普遍,因此虽然修复并非易事,但我们会优先处理它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多