我正在xUnit中编写单元测试用例。我正在编写用于打开数据库连接的单元测试用例。当数据库关闭时,我正在写负面案例。
下面是我与数据库建立连接的真实代码。
public IDbConnection CreateDirectDb2Connection(int attempt = 0)
{
try
{
var conn = new DB2Connection(BuildDB2ConnectionString());
conn.Open();
return conn;
}
catch (Exception ex)
{
logService.Debug($"Failed to create and open a connection, attempt {attempt + 1}/3, error: {ex}");
if (attempt < 2)
{
// Retry twice
return CreateDirectDb2Connection(attempt + 1);
}
throw ex;
}
}
下面是我的xUnit测试用例代码。
public class ContextProviderServiceTests
{
private readonly IContextProviderService contextProvider = Substitute.For<IContextProviderService>();
private readonly IDbCommand db2Command;
private readonly MainframeDirectAccessRepository mainframeRepository;
private readonly IDbConnection db2Connection;
public ContextProviderServiceTests()
{
db2Connection = Substitute.For<IDbConnection>();
db2Command = Substitute.For<IDbCommand>();
db2Command.Parameters.Returns(Substitute.For<IDataParameterCollection>());
db2Command.CreateParameter().Returns(Substitute.For<IDbDataParameter>());
commandParameters = new List<TestDataParameter>();
db2Command.Parameters.When(x => x.Add(Arg.Any<object>()))
.Do(c => commandParameters.Add(new TestDataParameter
{
Name = c.Arg<IDbDataParameter>().ParameterName,
Value = c.Arg<IDbDataParameter>().Value,
DbType = c.Arg<IDbDataParameter>().DbType
}));
}
[Fact]
public void CreateDirectDb2ConnectionFailure()
{
var connection = mockProvider.GetDependency<IContextProviderService();
connection.CreateDirectDb2Connection().Returns("I am not sure what to
return here");
}
有人可以帮我编写负面的单元测试用例(当DB关闭时)吗?任何帮助,将不胜感激。谢谢
答案 0 :(得分:1)
您应该在Interface Segregation的帮助下使用Dependency Inversion principle来遵守Inversion of Control和Dependency Injection。
这样,您可以在单元测试中创建一个MockDB2Connection,并将其注入到构造函数中,而在实际代码中,您将传递适当的DB2Connection。
假设您有这样的服务:
public class SomeService
{
private readonly IDbConnection _dbCOnnection;
public SomeService(IDbConnection dbConnection)
{
_dbCOnnection = dbConnection;
}
public async Task<IEnumerable<Foo>> GetFoos()
{
// Obviously don't do this in production code;
// just for demonstration purposes.
await _dbCOnnection.OpenAsync();
}
}
您可以像这样实现模拟连接类:
public interface IDbConnection
{
Task OpenAsync();
// Other required methods...
}
public class ThrowingDbConnection : IDbConnection
{
public Task OpenAsync()
{
throw new Exception("...");
}
}
public class FakeDbConnection : IDbConnection
{
public Task OpenAsync()
{
return Task.CompletedTask;
}
}
作为IoC容器,您有多种选择。微软的Microsoft.Extensions.DependencyInjection,AutoFac,CastleWindsor,Ninject等。选择一个适合您的需求。在大多数情况下,Microsoft或AutoFac在这里应该是不错的选择。