如何使用 dapper 和 nunit 为存储库服务中的更新功能编写集成测试?
How to write integration test for update function in repository services with dapper and nunit?
我正在开发一个 Blazor 服务器端项目。
当我尝试为我的存储库模式服务编写集成测试时,出现错误:
System.PlatformNotSupportedException : This platform does not support distributed transactions.
。
尝试使用第二个连接并查询所需数据是否真的保存会触发错误。
我的测试代码:
namespace CVUnitTests.IntegrationTests.Services
{
public class SkilServiceTest
{
[TestFixture]
public class YourFixture
{
private TransactionScope _scope;
private ISkillService _skillService;
private IConfigurationRoot _config;
[SetUp]
public void SetUp()
{
_config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_skillService = new SkillService(_config);
_scope = new TransactionScope();
}
[TearDown]
public void TearDown()
{
_scope.Dispose();
}
[Test]
public async Task UpdateSkill_NewSkillIsSaved()
{
var skillToUpdate = new Skill()
{
Name = "TestSkill",
Type = SkillType.Hardskill,
Category = "TestCategory"
};
await _skillService.UpdateSkill(skillToUpdate);
using IDbConnection connection = new SqlConnection(DatabaseUtils.GetConnectionString(_config));
var sql = "SELECT * FROM skill WHERE Name = TestSkill";
var queriedSkill = connection.QuerySingle<Skill>(sql);
Assert.AreEqual(queriedSkill, skillToUpdate);
}
}
}
}
我发现 Query 可用于实现此目的,但我无法将我的两个查询包装成一个 using 因为该服务正在打开自己的连接:
public Task<bool> UpdateSkill(Skill skill)
{
if (GetSkill(skill.Id) != null)
{
using IDbConnection dbConnection = new SqlConnection(_connectionString);
var parameters = new
{
Id = skill.Id,
skill.Name,
Skilltype = skill.Type == SkillType.Hardskill ? "TRUE" : "FALSE"
};
var sql = "update skill SET Name = @Name, Skilltype = @Skilltype where id = @Id";
dbConnection.Open();
var result = dbConnection.ExecuteAsync(sql, parameters).Result;
dbConnection.Close();
return Task.FromResult(true);
}
else
{
using IDbConnection dbConnection = new SqlConnection(_connectionString);
var parameters = new {skill.Name, Skilltype = skill.Type == SkillType.Hardskill ? 1 : 0};
var sql = "insert into skill (Name, Skilltype) values (@Name, @Skilltype)";
dbConnection.Open();
var result = dbConnection.ExecuteAsync(sql, parameters).Result;
dbConnection.Close();
return Task.FromResult(false);
}
我收到错误 This platform does not support distributed transactions.
即使我 运行 只是事务范围内的一个查询。
我也尝试从我的服务中读取 dbConnection
而不是创建一个新服务,但也没有成功。
我实际上可以在我的服务功能中使用多个,然后 return 技能,尽管它似乎有点将测试代码放入我的方法中。
有没有办法我仍然可以实现我想要的测试行为,或者我是否必须完全改变我的测试逻辑?
终于 运行 使用以下代码得到它:
{
public class SkilServiceTest
{
[TestFixture]
public class YourFixture
{
private TransactionScope _scope;
private ISkillService _skillService;
private IConfigurationRoot _config;
private DatabaseUtils _databaseUtils;
[SetUp]
public void SetUp()
{
_config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_skillService = new SkillService(_config);
_databaseUtils = new DatabaseUtils(_config);
//wipe data and create empty table to execute tests on empty tables
_databaseUtils.DropTable("Skill");
_databaseUtils.CreateSkillTable();
}
[TearDown]
public void TearDown()
{
//wipe data so database manipulation within tests has no effect afterwards and does not interfere later tests
_databaseUtils.DropTable("Skill");
}
[Test]
public async Task UpdateSkill_NewSkillIsSaved()
{
Skill skillToUpdate = new Skill()
{
Name = "TestSkill",
Type = SkillType.Softskill,
Category = "SomeCategory",
Id = 1
};
await _skillService.UpdateSkill(skillToUpdate);
string sql_query = "SELECT * FROM skill WHERE name = \'TestSkill\'";
Skill queriedSkill = null;
using (IDbConnection connection = new SqlConnection(DatabaseUtils.GetConnectionString(_config)))
{
connection.Open();
queriedSkill = connection.QuerySingle<Skill>(sql_query);
}
Assert.IsTrue(queriedSkill.Equals(skillToUpdate));
}
}
}
也必须更改 Update
:
public async Task<bool> UpdateSkillAsync(Skill skill)
{
var parameters = new {Id = skill.Id};
var sql_query = "SELECT * FROM skill WHERE id = @Id";
var queriedSkill = DbConnection_second.QuerySingleOrDefault<Skill>(sql_query, parameters);
if (queriedSkill != null)
{
var sql = "update skill SET Name = @Name, Type = @Type, Category = @Category where id = @Id";
var result = await DbConnection.ExecuteAsync(sql, skill);
return true;
}
else
{
var sql = "insert into skill (Name, Type, Category) values (@Name, @Type, @Category)";
var result = await DbConnection.ExecuteAsync(sql, skill);
return false;
}
}
我正在开发一个 Blazor 服务器端项目。
当我尝试为我的存储库模式服务编写集成测试时,出现错误:
System.PlatformNotSupportedException : This platform does not support distributed transactions.
。
尝试使用第二个连接并查询所需数据是否真的保存会触发错误。
我的测试代码:
namespace CVUnitTests.IntegrationTests.Services
{
public class SkilServiceTest
{
[TestFixture]
public class YourFixture
{
private TransactionScope _scope;
private ISkillService _skillService;
private IConfigurationRoot _config;
[SetUp]
public void SetUp()
{
_config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_skillService = new SkillService(_config);
_scope = new TransactionScope();
}
[TearDown]
public void TearDown()
{
_scope.Dispose();
}
[Test]
public async Task UpdateSkill_NewSkillIsSaved()
{
var skillToUpdate = new Skill()
{
Name = "TestSkill",
Type = SkillType.Hardskill,
Category = "TestCategory"
};
await _skillService.UpdateSkill(skillToUpdate);
using IDbConnection connection = new SqlConnection(DatabaseUtils.GetConnectionString(_config));
var sql = "SELECT * FROM skill WHERE Name = TestSkill";
var queriedSkill = connection.QuerySingle<Skill>(sql);
Assert.AreEqual(queriedSkill, skillToUpdate);
}
}
}
}
我发现 Query 可用于实现此目的,但我无法将我的两个查询包装成一个 using 因为该服务正在打开自己的连接:
public Task<bool> UpdateSkill(Skill skill)
{
if (GetSkill(skill.Id) != null)
{
using IDbConnection dbConnection = new SqlConnection(_connectionString);
var parameters = new
{
Id = skill.Id,
skill.Name,
Skilltype = skill.Type == SkillType.Hardskill ? "TRUE" : "FALSE"
};
var sql = "update skill SET Name = @Name, Skilltype = @Skilltype where id = @Id";
dbConnection.Open();
var result = dbConnection.ExecuteAsync(sql, parameters).Result;
dbConnection.Close();
return Task.FromResult(true);
}
else
{
using IDbConnection dbConnection = new SqlConnection(_connectionString);
var parameters = new {skill.Name, Skilltype = skill.Type == SkillType.Hardskill ? 1 : 0};
var sql = "insert into skill (Name, Skilltype) values (@Name, @Skilltype)";
dbConnection.Open();
var result = dbConnection.ExecuteAsync(sql, parameters).Result;
dbConnection.Close();
return Task.FromResult(false);
}
我收到错误 This platform does not support distributed transactions.
即使我 运行 只是事务范围内的一个查询。
我也尝试从我的服务中读取 dbConnection
而不是创建一个新服务,但也没有成功。
我实际上可以在我的服务功能中使用多个,然后 return 技能,尽管它似乎有点将测试代码放入我的方法中。
有没有办法我仍然可以实现我想要的测试行为,或者我是否必须完全改变我的测试逻辑?
终于 运行 使用以下代码得到它:
{
public class SkilServiceTest
{
[TestFixture]
public class YourFixture
{
private TransactionScope _scope;
private ISkillService _skillService;
private IConfigurationRoot _config;
private DatabaseUtils _databaseUtils;
[SetUp]
public void SetUp()
{
_config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_skillService = new SkillService(_config);
_databaseUtils = new DatabaseUtils(_config);
//wipe data and create empty table to execute tests on empty tables
_databaseUtils.DropTable("Skill");
_databaseUtils.CreateSkillTable();
}
[TearDown]
public void TearDown()
{
//wipe data so database manipulation within tests has no effect afterwards and does not interfere later tests
_databaseUtils.DropTable("Skill");
}
[Test]
public async Task UpdateSkill_NewSkillIsSaved()
{
Skill skillToUpdate = new Skill()
{
Name = "TestSkill",
Type = SkillType.Softskill,
Category = "SomeCategory",
Id = 1
};
await _skillService.UpdateSkill(skillToUpdate);
string sql_query = "SELECT * FROM skill WHERE name = \'TestSkill\'";
Skill queriedSkill = null;
using (IDbConnection connection = new SqlConnection(DatabaseUtils.GetConnectionString(_config)))
{
connection.Open();
queriedSkill = connection.QuerySingle<Skill>(sql_query);
}
Assert.IsTrue(queriedSkill.Equals(skillToUpdate));
}
}
}
也必须更改 Update
:
public async Task<bool> UpdateSkillAsync(Skill skill)
{
var parameters = new {Id = skill.Id};
var sql_query = "SELECT * FROM skill WHERE id = @Id";
var queriedSkill = DbConnection_second.QuerySingleOrDefault<Skill>(sql_query, parameters);
if (queriedSkill != null)
{
var sql = "update skill SET Name = @Name, Type = @Type, Category = @Category where id = @Id";
var result = await DbConnection.ExecuteAsync(sql, skill);
return true;
}
else
{
var sql = "insert into skill (Name, Type, Category) values (@Name, @Type, @Category)";
var result = await DbConnection.ExecuteAsync(sql, skill);
return false;
}
}