1

我在业务层有类似的方法。我是单元测试的新手,有时会感到困惑。对于一个想法,您能否建议,测试这种方法行为的更好方法是什么?我正在使用 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 中使用存储过程的函数的名称

它添加了一条新记录“类别”并返回其自动生成的 ID。如果它不为零,我们将该结果用于进一步处理。

我知道不应该对与数据库交谈感兴趣,下面是过程,只是为了让您了解数据库中发生了什么

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”返回的值
  • 你更喜欢测试什么而不是测试?如果可以列出会很棒
4

2 回答 2

2

根据适配器类型的特性,有几个选项。如果 AddDeveloperCategoryReturnID 是虚拟的或接口成员,您很可能使用测试替身(手动或动态模拟)将其行为替换为某些特定于测试的行为。

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

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

涉及数据库的自动化测试比纯单元测试更难编写和维护几个数量级,所以我倾向于选择重构选项。

另一方面,如果您认为存储过程代表了应由自动化测试保护的有价值的代码资产,那么您别无选择,只能编写数据库测试。

于 2010-01-19T18:36:30.343 回答
1

我首先进行转换Adapter.AddNewBlogCategoryReturnID(categoryName, ref categoryID),以便它不是通过引用返回变量,而是简单地返回值。

然后,我会将其提取到虚拟方法中。

为了测试AddNewCatRetID,我将扩展该类以制作可测试的版本,并覆盖该虚拟方法以返回int?存储在公共变量中的一个。

这样,当您测试以查看AddNewCatRetID在数据库中有 0 的情况下调用时会发生什么时,您实际上不需要在数据库中放入 0 - 您只需在类的可测试版本上设置该参数,当您的测试调用时AddNewCatRetID,如果访问数据库,它只会返回您设置的值。如果您可以避免访问数据库,则可以保证您的测试更快,并且由于它是 MS 生成的适配器,因此实际上不需要对其进行测试 - 您只关心您的方法对适配器返回的内容做了什么。

于 2010-01-19T19:14:36.420 回答