Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 单元测试与主键_Unit Testing - Fatal编程技术网

Unit testing 单元测试与主键

Unit testing 单元测试与主键,unit-testing,Unit Testing,我对单元测试还不熟悉,我想我可能已经陷入了困境 在单元测试中,处理主键的更好方法是什么 希望一个例子能勾勒出一些背景。如果要创建一个对象的多个实例,可以说是Person 我的单元测试是测试正在创建的正确关系 我的代码是创造荷马,他是巴特和丽莎的孩子。他还有一个朋友巴尼、卡尔和莱尼 我用一个接口分离了我的数据层。我的偏好是保持主键简单。例如,保存时,Person.ProductID=new Random.Next10000;而不是说Barney.PersonID=9110荷马.PersonID=3

我对单元测试还不熟悉,我想我可能已经陷入了困境

在单元测试中,处理主键的更好方法是什么

希望一个例子能勾勒出一些背景。如果要创建一个对象的多个实例,可以说是Person

我的单元测试是测试正在创建的正确关系

我的代码是创造荷马,他是巴特和丽莎的孩子。他还有一个朋友巴尼、卡尔和莱尼

我用一个接口分离了我的数据层。我的偏好是保持主键简单。例如,保存时,Person.ProductID=new Random.Next10000;而不是说Barney.PersonID=9110荷马.PersonID=3243等等

主键是什么并不重要,它只需要是唯一的

有什么想法吗

编辑:


对不起,我没说清楚。我的项目已设置为使用。数据层是完全独立的。我的问题的重点是,什么是实用的?

为什么使用随机数?关键点的数值重要吗?我只需要在数据库中使用一个序列并调用nextval。

考虑使用guid。它们在空间和时间上都是独一无二的,这意味着即使两台不同的计算机在同一时间生成它们,它们也将是不同的。换句话说,它们保证是独一无二的。随机数从来都不是好的,有相当大的碰撞风险

您可以使用静态类和方法生成Guid:

Guid.NewGuid();
假设这是C

编辑:


另一件事,如果您只想生成大量测试数据,而不必手工编写代码或编写大量for循环,请查看。开始使用流畅的方法可能有点困难,方法链接并不总是更好的可读性,但它是创建大量测试数据的好方法。

您可能已经深入到了几个可能最终导致您所问问题的角落

可能您担心重复使用主键、覆盖或错误加载数据库中已有的数据,例如,如果您是针对开发人员数据库而不是干净的测试数据库进行测试。在这种情况下,我建议您设置单元测试,以使用普通应用程序将使用的任何顺序创建其记录的PK,或者在干净、专用的测试数据库中进行测试

也许您关心的是,除了简单的1,2,3之外,您的PKs代码的有效性。请放心,在一个简单的应用程序中,这并不是一个典型的测试,因为大多数测试都不在应用程序的考虑范围之内:从序列生成一个数字是DB供应商的问题,在内存中跟踪一个数字是运行时/VM的问题

也许你只是想知道这类事情的最佳实践是什么。我建议您通过插入记录来设置数据库,然后使用应用程序本身用于插入记录的相同工具执行测试用例;假设您的应用程序代码将依赖于PKs的数据库销售序列号,如果是,请使用该序列号。最后,在您的测试用例执行之后,您的测试应该回滚对数据库所做的任何更改,以确保测试是多次执行的。这是我遗憾地试图描述一个名为的设计模式


数据库单元测试的基本问题是主键不能被重用。相反,每次创建新记录时,数据库都会创建一个新键,即使使用原始键删除记录也是如此

有两种基本方法可以解决这一问题:

从数据库中读取生成的主键并在测试中使用,或 每次测试时使用数据库的新副本。
您可以将每个测试放在一个事务中,并在测试完成时回滚事务,但是回滚事务并不总是使用主键;数据库引擎仍然不会重用在SQL Server中生成的密钥。

当通过另一段代码对数据库执行测试时,它不再是单元测试。之所以称之为,是因为您正在测试不同代码片段的交互以及它们如何集成在一起。这并不重要,但知道它很有趣

执行测试时,应发生以下情况:

开始数据库事务 插入已知的可能虚假的测试项目/实体 调用要测试的唯一函数 测试结果 回滚事务 这些事情应该发生在每一次测试中。使用NUnit,您可以在基类中只编写一次步骤1和步骤5,然后在每个测试类中继承步骤1和步骤5。NUnit将在基类中执行Setup和Teardown修饰方法

在步骤2中,如果您使用的是SQL,则必须编写查询,以便它们将PK编号返回到测试代码中

INSERT INTO Person(FirstName, LastName)
VALUES ('Fred', 'Flintstone');
SELECT SCOPE_IDENTITY(); --SQL Server example, other db vendors vary on this.
那你就可以这么做了

INSERT INTO Person(FirstName, LastName, SpouseId)
VALUES('Wilma', 'Flintstone', @husbandId);
SET @wifeId = SCOPE_IDENTITY();

UPDATE Person SET SpouseId = @wifeId
WHERE Person.Id = @husbandId;
SELECT @wifeId;
或者任何你需要的东西。

在步骤4中,如果使用SQL,则必须重新选择数据并测试返回的值


如果您有幸能够使用像NHibernate之类的像样的ORM,那么步骤2和4就不那么复杂了。

我有一个名为Unique的类,它生成唯一的对象字符串、整数等。它通过保持内部静态计数器来确保每次测试它们都是唯一的。该计数器值会随生成的每个键递增,并以某种方式包含在该键中

所以当我准备考试的时候

var Foo = {
    ID = Unique.Integer()
}
我喜欢这一点,因为它传达了这样一个信息:价值对于这个测试并不重要,只是唯一性

我有一个类似的类“Some”,它不能保证唯一性。我在需要测试的任意值时使用它。它对于枚举和实体对象很有用


这些都不是线程安全的或类似的,而是严格的测试代码。

您是否正在生成自己的主键?或者您允许DB为您生成它们?数据库在插入Guid时生成它们将是过分的,我对数据类型没有任何控制权。但是我会试试NBuilder!在商品数据库和廉价性能的时代,使用guid是一种新兴的最佳实践。这不再是过度杀戮。这对于漂亮的URL来说太长了。如果从int转换到Guid的唯一好处是一个开发人员可以对整个生产系统的一部分进行单元测试。那么是的,我认为这是过度的杀青!这就是我想要的。谢谢
INSERT INTO Person(FirstName, LastName)
VALUES ('Fred', 'Flintstone');
SELECT SCOPE_IDENTITY(); --SQL Server example, other db vendors vary on this.