我有几种方法可以连接到数据库,但我无法弄清楚如何为它们编写单元测试。以下是我正在谈论的一个例子。
public static User GetByPendingUserId(int a_PendingUserId)
{
User l_User = new User();
SqlConnection l_conn = DbHelp.CreateSqlConnection();
SqlCommand l_cmd = DbHelp.CreateCommand(l_conn, "User_Get");
l_cmd.Parameters.AddWithValue("@a_PendingUserId", a_PendingUserId);
DataTable l_result = new DataTable();
SqlDataAdapter l_adapter = new SqlDataAdapter(l_cmd);
l_conn.Open();
l_adapter.Fill(l_result);
l_conn.Close();
l_adapter.Dispose();
l_cmd.Dispose();
if (l_result.Rows.Count > 0)
{
User.SetMembers(l_result.Rows[0], l_User);
}
return l_User;
}
由于我正在编写单元测试而不是集成测试,因此我想测试方法的逻辑而不连接到实际的数据库。我怎么能这样做?
答案 0 :(得分:3)
假设您要测试依赖于这些方法的代码,您可以通过使用 Repository 模式实现此目的。您将系统的给定部分的数据访问封装到称为存储库的抽象中。因此,在您的情况下,您可能有一个用户存储库,它将包含以下接口和相应的实现。
public interface IUserRepository
{
User GetByPendingUserId(int a_PendingUserId)
}
请注意GetByPendingUserId
不再是静态的。
您现在可以实现此界面。因此,您的实际生产实现可能如下所示:
public class UserRepository : IUserRepository
{
public User GetByPendingUserId(int a_PendingUserId)
{
User l_User = new User();
SqlConnection l_conn = DbHelp.CreateSqlConnection();
SqlCommand l_cmd = DbHelp.CreateCommand(l_conn, "User_Get");
l_cmd.Parameters.AddWithValue("@a_PendingUserId", a_PendingUserId);
DataTable l_result = new DataTable();
SqlDataAdapter l_adapter = new SqlDataAdapter(l_cmd);
l_conn.Open();
l_adapter.Fill(l_result);
l_conn.Close();
l_adapter.Dispose();
l_cmd.Dispose();
if (l_result.Rows.Count > 0)
{
User.SetMembers(l_result.Rows[0], l_User);
}
return l_User;
}
}
出于测试目的,您现在可以实现另一个版本,返回您喜欢的任何数据以符合您的测试目标。也许它只返回一个new User
。它取决于你。关键是你不再依赖于实际的数据库,你可以专注于在单元测试中测试应用程序的逻辑。
public class TestUserRepository : IUserRepository
{
public User GetByPendingUserId(int a_PendingUserId)
{
return new User()
}
}
一旦你有更多这样的接口,你就可以看一下使用一个模拟框架,它可以让你在测试特定场景时有更多的灵活性。