NUnit-测试事务的单元测试用例



我有一个如下的方法。

我想为下面的方法写两个测试用例。

1( 提交数据的成功交易

2( 具有回滚数据的失败事务

如何编写一个包含事务的测试用例,并确定成功与失败?

public async Task<List<string>> UpdateRequest(MetaData data, List<string> Ids, string requestedBy)
{
var transaction = await _databaseUtility.CreateTransaction(ConnectionString);
var messages = new List<string>();
try
{
// Update data
await _testDal.Update(data, requestedBy, transaction);
// Update status
await _sampleDal.UpdateStatus(Ids, requestedBy, transaction);
// Update saved data
await _testDal.UpdateSavedData(data, requestedBy, transaction);
_databaseUtility.CommitTransaction(transaction);
}
catch (Exception exception)
{
_databaseUtility.RollbackTransaction(transaction);
}
return messages;
}

我认为您有两个问题:

  1. 您正在使用异步并等待单元内测试,这意味着您的代码将在真正完成任何操作之前继续运行。
    你可以读这个https://johnthiriet.com/removing-async-void/#

    我会解释这个陷阱,确保await _testDal.Update(data, requestedBy, transaction);Update((函数返回一个Task
    然后您可以用_testDal.Update(data, requestedBy, transaction).Wait()调用它进行单元测试
    await调用来获取常规代码。这将使您的测试代码等待更新完成,而常规代码保持原样。

  2. 我会使用NSubstitute这样的嘲讽服务https://nsubstitute.github.io/以模拟这些响应。mocking服务将使用反射来替换实现_testDal的接口或类
    这样,当您调用Update((函数时,您可以将某些参数传递给它,并在这些参数传递到函数中时抛出异常<并传递另一组参数并返回正确的消息。>

如果您希望传递不同的参数,可以使用NunitTestCase(new[] params...)并将不同的参数集传递给相同的单元测试。然而,对于PassTest和FailTest,我将使用2个或多个不同的测试。

您可以使用NUnit内置的TestCaseSource属性和TestCaseData类来实现它。

[TestCaseSource(nameof(TestCases))]
public List<string> TestTransaction(MetaData data, List<string> ids, string requestedBy)
{
return testObject.UpdateRequest(data, ids, requestedBy).GetAwaiter().GetResult();
}
public static IEnumerable TestCases
{
get
{
//successful
yield return new TestCaseData(new MetaData(), new List<string> { "1", "2" }, "test").Returns(new List<string> { "test1", "test2" });
//failed
yield return new TestCaseData(null, new List<string> { "1", "2" }, "test").Returns(new List<string> { "test1", "test2" });
//another failed
yield return new TestCaseData(new MetaData(), new List<string> { "1", "2" }, string.Empty).Returns(new List<string> { "test1", "test2" });
}
}

这里有几个要点

  • 为什么在UpdateRequest方法中需要消息的List?它是仅初始化,不添加值。在上面的代码片段中,从UpdateRequest方法返回的消息列表与预期结果简单匹配,但您也可以在此处编写任何Assert
  • 失败的事务取决于您的逻辑,您可以传递无效的导致异常的数据,在我使用的代码段中为空MetadatarequestedBy
  • async Task<List<string>>返回结果同步执行到与期望的返回结果CCD_ 15相匹配。异步测试用例源代码在NUnit github中是公开的提案

作为一个选项,您还可以为成功和失败的事务编写单独的测试,并异步调用UpdateRequest方法。

到目前为止,您还没有分享组件的详细信息,很难对DAL做出假设,但如果您想对Update方法使用mock,您可以尝试Moq库和Task.FromResult方法来获取响应/返回值,如本答案中所述

最新更新