驱动测试开发纯粹主义者可能会说每个测试里只应该有一个断言。我想这个原则有时候可以灵活处理,像下面测试一个对象的属性值时:

    public Product Map(ProductDto productDto) 
    { 
        var product = new Product() 
        {  
            ID = productDto.ID, 
            Name = productDto.ProductName, 
            BasePrice = productDto.Price 
        }; 
        
        return product; 
    }

  我不认为为每个属性写一个独立的测试方法进行断言是有必要的。下面是我如何写这个测试方法的:

    [TestMethod] 
    public void ProductMapperMapsToExpectedProperties() 
    { 
        // Arrange 
        var mapper = new ProductMapper(); 
        var productDto = new ProductDto() 
        { 
            ID = "sp-001", 
            Price = 10m, 
            ProductName = "Super Product"
        }; 
        
        // Act 
        Product product = mapper.Map(productDto); 
        
        // Assert 
        Assert.AreEqual(10m, product.BasePrice); 
        Assert.AreEqual("sp-001", product.ID); 
        Assert.AreEqual("Super Product", product.Name); 
    }

  4、先写程序后写测试

  我坚持认为,驱动测试开发的意义远高于测试本身。正确的实施驱动测试开发能巨大的提高开发效率,这是一种良性循环。我看到很多开发人员在开发完某个功能后才去写测试方法,把这当成一种在提交代码前需要完成的行政命令来执行。事实上,补写测试代码只是驱动测试开发的一个内容。

  如果不是按照先写测试后写被测试程序的红,绿,重构方法原则,测试编写很可能会变成一种体力劳动。

  如果想培养你的单元测试习惯,你可以看一些关于TDD的材料,比如The String Calculator Code Kata。

  5、测试的过细

  请检查下面的这个方法:

    public Product GetByID(string id) 
    { 
        return _productRepository.GetByID(id); 
    }

  这个方法真的需要测试吗?不,我也认为不需要。

  驱动测试纯粹主义者可能会坚持认为所有的代码都应该被测试覆盖,而且有这样的自动化工具能扫描并报告程序的某部分内容没有被测试覆盖,然而,我们要当心,不要落入这种给自己制造工作量的陷阱。

  很多我交谈过的反对驱动测试开发的人都会引用这点来作为不写任何测试代码的主要理由。我对他们的回复是:只测试你需要测试的代码。我的观点是,构造器,geter,setter等方法没必要特意的测试。让我们来加深记忆一下我前面提到的经验论:

  为方法里的每个IF,And,Or,Case,For,While等条件写出独立的测试方法。

  如果一个方法里没有任何一个上面提到的条件语句,那它真的需要测试吗?

  祝测试愉快!