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

发布于 2024-08-18 09:14:30 字数 949 浏览 2 评论 0 原文

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

它添加新记录“类别”并返回其自动生成的 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”返回的值,
  • 您希望测试什么以及不测试?如果能列出就太好了

I have similar methods in the business layer. I am new to unit testing and sometimes get confused. For an idea, can you suggest, what will be a better approach to test this method
behaviour? I am using C# NUnit and Moq

public int? AddNewCatRetID(string categoryName)
{
  int? categoryID = 0;
  Adapter.AddNewBlogCategoryReturnID(categoryName, ref categoryID);

  if (categoryID.HasValue)
    return categoryID;

  return 0;
}

where

Adapter = Visual Studio 2008, Data Set Designer generated TableAdater

AddDeveloperCategoryReturnID() = Name of a function which utilises a Stored procedure in DB

It adds a new record, "Category" and returns its auto generated ID. If it is non zero, we take that result for further processing.

I know should not be interested in talking to Database, below is the procedure, just to give an idea about what is going on in 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

some issues

  • how to check the values returned using "ref" from the method
  • what will you prefer to test and not to test? will be great if can list

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温柔女人霸气范 2024-08-25 09:14:30

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

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

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

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

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

There are several options depending on the characteristics of the Adapter type. If AddDeveloperCategoryReturnID is virtual or an interface member, you can most likely use a Test Double (either a hand-rolled one or a dynamic mock) to replace its behavior with some test-specific behavior.

If is a non-virtual method, you have two options:

  • Refactor the method to make it more testable.
  • Write an automated test that involves a database round-trip.

Automated tests that involve the database are orders of magnitudes more difficult to write and maintain than pure unit tests, so I would tend to shoot for the refactoring option.

On the other hand, if you think that the stored procedure represents a valuable code asset that should be protected by an automated test, you have no recourse but to write the database test.

晚风撩人 2024-08-25 09:14:30

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

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

为了测试 AddNewCatRetID,我将扩展该类以创建可测试版本,并重写该虚拟方法以返回存储在公共变量中的 int?

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

I'd first convert Adapter.AddNewBlogCategoryReturnID(categoryName, ref categoryID) so that instead of returning a variable by reference, it simply returned the value.

Then, I would extract that into a virtual method.

To test AddNewCatRetID, I would extend the class to make a testable version, and override that virtual method to return an int? stored in a public variable.

That way, when you test to see what happens when you call AddNewCatRetID in a situation where there's a 0 in the database, you don't need to actually put a 0 in the database - you just set that parameter on the testable version of your class, and when your test calls AddNewCatRetID, instead if hitting the database, it just returns the value you set. Your test is guaranteed to be faster if you can avoid hitting the database, and since it's MS's generated adapter, there's not really a need to test it - you only care about what your method does with what the adapter returns.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文