如何对以下方法进行单元测试,使用“ref”返回值

时间:2010-01-19 18:11:59

标签: c# unit-testing stored-procedures nunit ref

我在业务层中有类似的方法。我是单元测试的新手,有时会感到困惑。对于一个想法,你能否提出一个更好的方法来测试这种方法 行为?我正在使用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

一些问题

  • 如何使用方法
  • 中的“ref”检查返回的值
  • 您更喜欢测试而不测试?如果能列出
  • 会很棒

2 个答案:

答案 0 :(得分:2)

根据适配器类型的特性,有几种选择。如果AddDeveloperCategoryReturnID是虚拟接口成员,您很可能使用Test Double(手动滚动或动态模拟)来替换其行为具有一些特定于测试的行为。

如果是非虚拟方法,您有两种选择:

  • 重构方法以使其更易于测试。
  • 编写一个涉及数据库往返的自动化测试。

涉及数据库的自动化测试比纯单元测试更难以编写和维护,因此我倾向于为重构选项进行拍摄。

另一方面,如果您认为存储过程代表了应该通过自动化测试保护的有价值的代码资产,那么您无需追索,而是编写数据库测试。

答案 1 :(得分:1)

我首先转换Adapter.AddNewBlogCategoryReturnID(categoryName, ref categoryID),这样它就不会通过引用返回变量,而只返回值。

然后,我将其提取为虚拟方法。

要测试AddNewCatRetID,我会扩展该类以生成可测试版本,并覆盖该虚拟方法以返回存储在公共变量中的int?

这样,当你测试看到在数据库中有0的情况下调用AddNewCatRetID时会发生什么,你不需要在数据库中实际设置0 - 你只需要设置您的类的可测试版本上的参数,以及当您的测试调用AddNewCatRetID时,如果访问数据库,它只返回您设置的值。如果你可以避免命中数据库,你的测试肯定会更快,因为它是MS生成的适配器,所以不需要测试它 - 你只关心你的方法对适配器返回的内容做了什么。