如何对依赖的cpde进行单元测试

时间:2019-12-29 10:32:52

标签: c# unit-testing nunit

我有一些看起来像这样的代码:

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...
    }
}

我可以对隔离的类“ B”的创建进行单元测试,但是我无法提出对隔离的“ A”类进行单元测试的解决方案。

为了使代码正常工作,传递给'A'的json必须包含一个属性,该属性可以解析为类型正确的'B'类型的对象;因此,当我尝试对'A'进行单元测试时,输入json不仅需要具有'A'的数据(即'A'的属性1和2),而且还必须具有'B'的数据。对我来说,这看起来有点不可思议,因为这样做也将在'A'的单元测试中测试分类'B'...

问题是,“ A”需要正确设置property3(类型为“ B”的一种)才能正常工作,因此如果没有“ B”,我将无法构造“ A”。

这可能看起来没什么大问题,但是当链扩展到类'C'和'D'等时,情况变得更糟。

它几乎与您需要对整辆汽车进行单元测试时存在相同的问题。您可以对它的零件(例如发动机,车轮等)进行单元测试。但是,要对汽车本身进行单元测试,您需要具有有效的发动机和有效的车轮。

我认为我有点遗漏了某个地方,做错了事,但我无法弄清楚。

有人会这样启发我如何正确地对这种情况进行单元测试吗?

1 个答案:

答案 0 :(得分:1)

我将在这里对我的代码进行一些认真的重构。

  1. 我会将所有序列化/反序列化代码都放在类范围之外。这样,您可以正确地对序列化/反序列化进行单元测试,并为此具有通用机制。创建类似于Interface的{​​{1}}并注入到类A中。这样,您可以使用类似IMySerializer的东西进行模拟并控制重现值。

  2. 伪造属性B。无论您对属性B进行什么操作,都应该100%预期。如果B下的属性C改变了行为,则类Moq仍应正确执行单元测试。只有A类可以在其单元测试中失败。

  3. 如果要测试整个汽车的序列化,则无法解决。您需要提供整个字符串。具有所有子属性。真的有理由这样做吗?

扩展三个。假设您有一辆汽车。它具有“刹车”和“加速器”属性。您可以同时选择两个类,并模拟Car的功能以始终具有期望值。发生C时,将返回一些新值。该值应被控制。使用Accelerator.Push()的控制值和上一个控制值,汽车应该对当前速度进行单元测试。该速度应该进行单元测试。