【问题标题】:How to test in xunit complex method如何在 xunit 复数方法中进行测试
【发布时间】:2019-06-14 17:39:48
【问题描述】:

如何在 asp.net core 2.0 中进行测试,该方法存在于与我的测试项目不同的项目中?比如这样:

 public partial class LoanRequestServiceController : BaseServiceController
 {
    public ServiceDTO<AP_CBO> AddCBO(AP_CBO cbo)
    {
        ServiceDTO<AP_CBO> dto = new ServiceDTO<AP_CBO>();

        try
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
            {
                cbo.ID_CBO = 333;
                dto.Data = cbo;
                scope.Complete();
            }
        }
        catch (Exception ex)
        {
            dto.Error = new ServiceError(ex);
            Globals.Logger.Error(ex);
        }
        finally
        {
            //Globals.CastleComponentsContainer.Release(LoanRequestDAL);
        }
        return dto;
    }
 }

我测试了一些“轻量级”方法,例如服务方法是否返回 SucessCode 并且可以正常工作。 这是我的测试类:

    [Theory]
    [InlineData("/Sample/AddCBO")]
    public async Task Test_AddCBO(string url)
    {
        //Arrange
        var client = _factory.CreateClient();

        //Act
        var response = await client.GetAsync(url);

        //Assert

        response.EnsureSuccessStatusCode();
        //Compare two dto objects AP_CBO
        //object expected = new AP_CBO { properties... }
        // object responseObject = response.Content...
        //Assert.Equal(expected, responseObject);
    }

我不知道如何测试具有多个属性的对象。 也许我需要使用起订量?从理论上讲,这种方法会转到 DAL(数据库访问层)并从数据库打包对象返回并返回到 api,或者在我的情况下返回到测试。

【问题讨论】:

  • 考虑使用FluentAssertions 库,该库提供了不错的(流利的)api,用于断言具有期望的实际数据。在你的情况下,它只是responseObject.Should().BeEquivalentTo(expected)

标签: c# asp.net-core xunit


【解决方案1】:

这里的详细解释是相当长的话题;我认为如果您遵循示例并阅读详细信息会更好。

我假设你要写单元测试;对于单元测试,我可以推荐这个可能对你有帮助的教程。 check this please

【讨论】:

    【解决方案2】:

    首先,您必须决定要编写的测试级别。

    如果您正在编写 单元测试,您应该模拟所有外部集成(在您的情况下,我可以识别 HTTP 请求 -> 控制器控制器 -> 数据库)。这是功能测试的基础。因此,如果您正在编写单元测试,是的,您应该使用模拟框架,例如 NSubstitute 或 Moq(并且只通过调用它来测试您的方法的行为)。

    您发布的测试示例在我看来就像一个集成测试,因为您包含了集成HTTP 请求 -> 控制器。在这种情况下,我将使用数据(如果相关)为数据库播种并实际调用您的 API 端点(正如您已经在做的那样)。

    要检查 ASP.Net Core 中响应的内容 (DTO),您必须执行以下操作:

    // ...
    var response = await client.GetAsync(url);
    
    response.EnsureSuccessStatusCode();
    
    var content = await httpResponseMessage.Content.ReadAsStringAsync();
    var serviceDto = JsonConvert.DeserializeObject<ServiceDTO<AP_CBO>>(content); // Only for Json
    // Validate serviceDto
    

    【讨论】:

    • 是的,我明白了。哪个更好?功能测试还是集成测试?以及当我将某个对象作为参数传递时如何进行测试?例如,我如何测试一个名为 SaveCBO(AP_CBO entity) 的方法,该方法将调用数据库并实际保存它?例如,在集成测试中?那我就用 PostAsync(url, body)?
    • 一条评论中有很多问题。测试策略的选择基本上取决于您。有时,当我的控制器操作不包含很多业务逻辑时,我认为集成测试就足够了。但是,如果您的方法中有很多事情发生,我建议您编写单元测试来验证预期的行为,并可能添加一些集成测试来验证该操作实际上是可调用的。
    • 至于如何将对象作为参数传递,您只需像在 ASP.Net Core 中通常所做的那样,将主体添加到请求中。在单元测试中,您只能使用对象调用方法。
    • 我正在尝试让它工作,编写 JsonConvert 库(第二个选项),但我的测试失败并出现错误:Message: The following constructor parameters did not have matching fixture data: WebApplicationFactory1 factory `。我无法弄清楚这个错误。我真的只是复制了你的例子。
    • 哪一行导致了这个异常?你能在没有我添加的行的情况下成功执行测试吗? (var content = await httpResponseMessage.Content.ReadAsStringAsync(); var serviceDto = JsonConvert.DeserializeObject&lt;ServiceDTO&lt;AP_CBO&gt;&gt;(content);)
    猜你喜欢
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多