我在后面的asp.net代码中有以下方法,它调用存储过程并返回结果。我不确定我应该写的单元测试方法的定义来测试这种方法。
public List<BlogDetail> GetData()
{
List<BlogDetail> allBlogDetail = new List<BlogDetail>();
using (var db = new BloggingContext("CodeFirstSampleConnectionString")) //name=CodeFirstSample
{
allBlogDetail = db.Database.SqlQuery<BlogDetail>("uspGetAllBlogs").ToList();
}
return allBlogDetail;
}
以下是我为测试此方法而编写的单元测试方法。据我所知,在单元测试中进行数据库调用并不是一个好习惯,我通过在单元测试方法中调用数据库来违反。
public void GetDataTest()
{
Default target = new Default();
List<BlogDetail> expected = new List<BlogDetail>();
List<BlogDetail> actual = new List<BlogDetail>();
using (var db = new BloggingContext("DemoConnectionString"))
{
expected = db.Database.SqlQuery<BlogDetail>("uspGetAllBlogs").ToList();
}
actual = target.GetData();
Assert.AreEqual(expected.Count, actual.Count);
for (int i = 0; i < expected.Count; i++)
{
Assert.AreEqual(expected[i].BlogID, actual[i].BlogID);
Assert.AreEqual(expected[i].BlogName, actual[i].BlogName);
Assert.AreEqual(expected[i].PostID, actual[i].PostID);
Assert.AreEqual(expected[i].PostTitle, actual[i].PostTitle);
Assert.AreEqual(expected[i].PostContent, actual[i].PostContent);
}
}
我已经读过单元测试应该是可重复的和可预测的,并且通过上面的方法我违反了这两个规则。
此单元测试至少需要30秒才能在本地数据库中运行,显然在使用远程数据库进行测试时需要更长的时间。
存储过程的结果也是不可预测的,因为存储过程在不同时间调用时可以返回变量记录。由于数据库定期提供数据。
我不知道单元测试方法的定义。我的单元测试方法是否正确?我需要采取不同的方法吗?请帮忙。
答案 0 :(得分:2)
您想测试GetData()
方法是否调用uspGetAllBlogs
SP。在您当前的代码中,这是不可能的,因为GetData()
方法做得太多了。
当存储库注入Default
:
interface IBlogRepository
{
List<BlogDetail> GetAllBlogs();
}
class BlogRepository : IBlogRepository
{
public List<BlogDetail> GetAllBlogs()
{
using (var db = new BloggingContext("CodeFirstSampleConnectionString"))
{
return db.Database.SqlQuery<BlogDetail>("uspGetAllBlogs").ToList();
}
}
}
class Default
{
private readonly IBlogRepository _blogRepository;
public Default(IBlogRepository blogRepository)
{
_blogRepository = blogRepository;
}
public List<BlogDetail> GetData()
{
return _blogRepository.GetAllBlogs();
}
}
现在您可以在测试时模拟您的存储库,并且您只需要验证 您的存储库的GetAllBlogs()
方法被调用,而不是它返回的:< / p>
public void GetDataTest()
{
var mockRepository = new Mock<IBlogRepository>();
mockRepository.Setup(r => r.GetAllBlogs()).Returns(new List<BlogDetail>());
Default target = new Default(mockRepository.Object);
var actual = target.GetData();
Assert.AreEqual(0, actual.Count);
mockRepository.Verify(r => r.GetAllBlogs(), Times.Once());
}
在此之后,您将需要对BlogRepository
进行单元测试。为此,您必须与BloggingContext
对接,并使用适当的参数验证调用Database.SqlQuery()
方法,依此类推。
答案 1 :(得分:0)
对这个问题的回答将会很长...尝试阅读关于UI(asp.net页面及其代码背后)和应用程序逻辑的分离。看一下依赖注射可能。你只需要将Repository
模式或类似的东西注入你的类并让它获取数据。这样,您可以注入将返回预定义数据的存储库对象的模型实现。