如何对依赖代码进行单元测试
How to unit test dependant cpde
我有一些代码如下所示:
public class A()
{
public string property1 {get; private set;}
public string property2 {get; private set;}
public B property3 {get; private set;}
public A(string json)
{
ReadProperty1(json);
ReadProperty2(json);
ReadProperty3(json);
}
void ReadProperty1(string json){...}
void ReadProperty2(string json){...}
void ReadProperty3(string json){...}
}
public class B()
{
public string property1 {get; private set;}
public string property2 {get; private set;}
public B(string json)
{
//Read properties 1 and 2...
}
}
我可以单独对 class 'B' 的创建进行单元测试,但我想不出单元测试的解决方案 class 'A'隔离。
为了使代码正常工作,传递给 'A' 的 json 必须包含一个 属性,它可以被解析为 'B' 类型的对象,格式正确;所以当我尝试对 'A' 进行单元测试时,输入 json 不仅需要 'A' 的数据(即 'A' 的属性 1 和 2),而且也属于 'B'。对我来说,这看起来有点奇怪,因为这样做也会在 'A'...
的单元测试中测试类 'B'
问题是 'A' 需要 属性3('B' 类型的那个)正确设置才能工作,所以我不能在没有 'A' 的情况下构建 'A' =27=].
这看起来可能不是什么大问题,但当链延伸到 class 'C' 和 'D' 等时,情况会变得更糟
它或多或少与您需要对整辆车进行单元测试的问题相同。您可以对它的部件进行单元测试,例如发动机、车轮等。但是为了对汽车本身进行单元测试,您需要有一个有效的发动机和有效的车轮。
我觉得我有点漏掉了重点,做错了什么,我就是想不通。
谁能告诉我如何正确地对这种情况进行单元测试?
我会在这里认真重构我的代码。
我会将所有 serialization/deserialization 代码都放在 class 范围之外。这样您就可以正确地对 serialization/deserialization 进行单元测试,并为此拥有一个通用机制。创建一个像 IMySerializer
这样的 Interface
并注入到 class A 中。这样你就可以使用像 Moq
这样的东西来模拟并控制返回值。
伪造 属性 B。无论你用 属性 B 做什么,都应该是 100% 的预期。如果 B 下的 属性 C 改变了行为,那么 Class A
仍应正确执行单元测试。只有 Class C
应该在他们的单元测试中失败。
如果你是测试整车序列化,那就没办法了。您需要提供整个字符串。具有所有子属性。不过真的有这样做的理由吗?
扩展三个。假设你有一辆汽车。它具有 Brakes 和 Accelerator 属性。您可以 Moq classes 并模拟汽车的功能以始终具有预期值。当 Accelerator.Push()
发生时,返回一些新值。这个值应该控制。有了Brakes.Push()
的控制值和前一个,小车应该对当前速度进行单元测试。该速度应该进行单元测试。
我有一些代码如下所示:
public class A()
{
public string property1 {get; private set;}
public string property2 {get; private set;}
public B property3 {get; private set;}
public A(string json)
{
ReadProperty1(json);
ReadProperty2(json);
ReadProperty3(json);
}
void ReadProperty1(string json){...}
void ReadProperty2(string json){...}
void ReadProperty3(string json){...}
}
public class B()
{
public string property1 {get; private set;}
public string property2 {get; private set;}
public B(string json)
{
//Read properties 1 and 2...
}
}
我可以单独对 class 'B' 的创建进行单元测试,但我想不出单元测试的解决方案 class 'A'隔离。
为了使代码正常工作,传递给 'A' 的 json 必须包含一个 属性,它可以被解析为 'B' 类型的对象,格式正确;所以当我尝试对 'A' 进行单元测试时,输入 json 不仅需要 'A' 的数据(即 'A' 的属性 1 和 2),而且也属于 'B'。对我来说,这看起来有点奇怪,因为这样做也会在 'A'...
的单元测试中测试类 'B'问题是 'A' 需要 属性3('B' 类型的那个)正确设置才能工作,所以我不能在没有 'A' 的情况下构建 'A' =27=].
这看起来可能不是什么大问题,但当链延伸到 class 'C' 和 'D' 等时,情况会变得更糟
它或多或少与您需要对整辆车进行单元测试的问题相同。您可以对它的部件进行单元测试,例如发动机、车轮等。但是为了对汽车本身进行单元测试,您需要有一个有效的发动机和有效的车轮。
我觉得我有点漏掉了重点,做错了什么,我就是想不通。
谁能告诉我如何正确地对这种情况进行单元测试?
我会在这里认真重构我的代码。
我会将所有 serialization/deserialization 代码都放在 class 范围之外。这样您就可以正确地对 serialization/deserialization 进行单元测试,并为此拥有一个通用机制。创建一个像
IMySerializer
这样的Interface
并注入到 class A 中。这样你就可以使用像Moq
这样的东西来模拟并控制返回值。伪造 属性 B。无论你用 属性 B 做什么,都应该是 100% 的预期。如果 B 下的 属性 C 改变了行为,那么 Class
A
仍应正确执行单元测试。只有 ClassC
应该在他们的单元测试中失败。如果你是测试整车序列化,那就没办法了。您需要提供整个字符串。具有所有子属性。不过真的有这样做的理由吗?
扩展三个。假设你有一辆汽车。它具有 Brakes 和 Accelerator 属性。您可以 Moq classes 并模拟汽车的功能以始终具有预期值。当 Accelerator.Push()
发生时,返回一些新值。这个值应该控制。有了Brakes.Push()
的控制值和前一个,小车应该对当前速度进行单元测试。该速度应该进行单元测试。