我在业务层中有类似的方法。我是单元测试的新手,有时会感到困惑。对于一个想法,你能否提出一个更好的方法来测试这种方法 行为?我正在使用C#NUnit和Moq
public int? AddNewCatRetID(string categoryName)
{
int? categoryID = 0;
Adapter.AddNewBlogCategoryReturnID(categoryName, ref categoryID);
if (categoryID.HasValue)
return categoryID;
return 0;
}
其中
Adapter
= Visual Studio 2008,数据集设计器生成TableAdater
AddDeveloperCategoryReturnID()
=在DB
它添加了一个新记录“Category”并返回其自动生成的ID。如果它不为零,我们将该结果用于进一步处理。
我知道不应该对与数据库交谈感兴趣,下面是程序,只是为了了解DB中发生了什么
PROCEDURE [dbo].[AddDeveloperCategoryReturnID]
@NAME NVARCHAR(MAX),
@CATEGORY_ID INT OUTPUT
AS
BEGIN
INSERT INTO [AllTimeGreatProgrammersDateBase].dbo.CATEGORIES(NAME )
VALUES (@NAME );
SET @CATEGORY_ID = SCOPE_IDENTITY();
SELECT @CATEGORY_ID;
END
一些问题
答案 0 :(得分:2)
根据适配器类型的特性,有几种选择。如果AddDeveloperCategoryReturnID是虚拟或接口成员,您很可能使用Test Double(手动滚动或动态模拟)来替换其行为具有一些特定于测试的行为。
如果是非虚拟方法,您有两种选择:
涉及数据库的自动化测试比纯单元测试更难以编写和维护,因此我倾向于为重构选项进行拍摄。
另一方面,如果您认为存储过程代表了应该通过自动化测试保护的有价值的代码资产,那么您无需追索,而是编写数据库测试。
答案 1 :(得分:1)
我首先转换Adapter.AddNewBlogCategoryReturnID(categoryName, ref categoryID)
,这样它就不会通过引用返回变量,而只返回值。
然后,我将其提取为虚拟方法。
要测试AddNewCatRetID
,我会扩展该类以生成可测试版本,并覆盖该虚拟方法以返回存储在公共变量中的int?
。
这样,当你测试看到在数据库中有0的情况下调用AddNewCatRetID
时会发生什么,你不需要在数据库中实际设置0 - 你只需要设置您的类的可测试版本上的参数,以及当您的测试调用AddNewCatRetID
时,如果访问数据库,它只返回您设置的值。如果你可以避免命中数据库,你的测试肯定会更快,因为它是MS生成的适配器,所以不需要测试它 - 你只关心你的方法对适配器返回的内容做了什么。