代码之家  ›  专栏  ›  技术社区  ›  Joseph

检查参数是否正确使用的最佳测试模式是什么?

  •  1
  • Joseph  · 技术社区  · 14 年前

    //Arrange
    var bucketsOfFun = new BucketGame();
    
    var balls = new List<IBall>
                    {
                        new Ball { Color = Color.Red },
                        new Ball { Color = Color.Blue },
                        new Ball { Color = Color.Yellow },
                        new Ball { Color = Color.Orange },
                        new Ball { Color = Color.Orange }
                    };
    
    //Act
    bucketsOfFun.HaveFunWithBucketsAndBalls(balls);
    
    //Assert ???
    

    我的麻烦就从这里开始了。我的方法是这样做:

    public void HaveFunWithBucketsAndBalls(IList<IBall> balls)
    {
        //group all the balls together according to color
        var blueBalls = GetBlueBalls(balls);
        var redBalls = GetRedBalls(balls);
        // you get the idea
    
        HaveFunWithABucketOfBalls(blueBalls);
        HaveFunWithABucketOfBalls(redBalls);
        // etc etc with all the different colors
    }
    
    public void HaveFunWithABucketOfBalls(IList<IBall> colorSpecificBalls)
    {
        //doing some stuff here that i don't care about 
        //for the test i'm writing right now
    }
    

    我想说的是,每次我叫HaveFunWithABucketOfBalls的时候,我都是用一个红色的球,一个蓝色的球,一个黄色的球,然后是两个橙色的球。

    如果我可以断言该行为,那么我就可以验证该方法是否正在执行我希望它执行的操作,这就是正确地对球进行分组。

    2 回复  |  直到 14 年前
        1
  •  2
  •   David Tchepak    14 年前

    测试这一点的一种方法是,将处理特定颜色球的责任分解为依赖关系,例如, :

    //Arrange
    var bucketHandler = MockRepository.GenerateStub<IBuckerHandler>();
    var bucketsOfFun = new BucketGame(bucketHandler);
    ...
    //Assert
    bucketHandler.AssertWasCalled(x => x.HaveFunWithABucketOfBalls(redBalls));
    bucketHandler.AssertWasCalled(x => x.HaveFunWithABucketOfBalls(greenBalls));
    

    这个测试就是检查你的 正确调用 玩得开心 在模拟对象上。这可能仍然会给您指定每个参数应该是什么带来麻烦。反过来,您可以通过将分类球的责任推到一个新的依赖项上,从而使测试更容易(代价是引入更多的抽象)。然后你会得到这样的结果:

    //Arrange
    var balls = new List<IBall>(); //Can really be anything, we just need the object reference
    var greenBalls = new List<IBall>();
    var redBalls = new List<IBall>();
    var sortedBalls = new [] { greenBalls, redBalls };
    
    var bucketHandler = MockRepository.GenerateStub<IBucketHandler>();
    var ballSorter = MockRepository.GenerateStub<IBallSorter>();
    ballSorter.Stub(x => x.Sort(balls)).Return(sortedBalls);
    
    var bucketsOfFun = new BucketGame(bucketHandler, ballSorter);
    
    //Act
    bucketsOfFun.HaveFunWithBucketsAndBalls(balls);
    
    //Assert
    bucketHandler.AssertWasCalled(x => x.HaveFunWithABucketOfBalls(greenBalls));
    bucketHandler.AssertWasCalled(x => x.HaveFunWithABucketOfBalls(redBalls));
    

    为了通过这个测试 巴克游戏 :

    public BucketGame(IBucketHandler bucketHandler, IBallSorter ballSorter) 
    {
      this.bucketHandler = bucketHandler;
      this.ballSorter = ballSorter;
    }
    
    public void HaveFunWithBucketsAndBalls(IList<IBall> balls)
    {
        //group all the balls together according to color
        var sortedBalls = ballSorter.Sort(balls);
        foreach (var groupOfBalls in sortedBalls) 
        {
            bucketHandler.HaveFunWithABucketOfBalls(groupOfBalls);
        }
    }
    

    巴克游戏 逻辑。现在您需要为IBallSorter实现编写单元测试,以检查它是否根据需要按颜色对球进行排序。这些测试可能不需要任何模拟,您只需输入数据并断言您得到的数据是您所期望的。

        2
  •  0
  •   Berryl    14 年前

    interface IBucketGame{
        void HaveFunWithBucketsAndBalls(IList<IBall> balls)
        void HaveFunWithSpecificBalls(IList<IBall> balls)
    }
    

    [Test]
    public void HaveFunWithBucket_IfMoreThanOneColor_CallsHaveFunWithSpecificBallsForSpecificColor()
        {
            //Arrange
            var bucketsOfFun = MockRepository.GenerateMock<IBucketGame>();
    
            IBall expColor_1 = new Ball(Color.Red);
            IBall expColor_2 = new Ball(Color.Green);
            IBall expColor_3 = new Ball(Color.Red);
            var startlist = new List<IBall>{expColor_1, expColor_2, expColor_3};
            var onlyRedBalls = new List<IBall>{expColor_1, expColor_3};
            var onlyGreenBalls = new List<IBall>{expColor_2};
    
            //Act
            bucketsOfFun.HaveFunWithBucketsAndBalls(balls);
    
            //Assert 
            bucketsOfFun.AssertWasCalled(x=>x.HaveFunSpecificBalls(Arg<IEnumerable<IBall>>.List.Equal(onlyRedBalls)));
            bucketsOfFun.AssertWasCalled(x=>x.HaveFunSpecificBalls(Arg<IEnumerable<IBall>>.List.Equal(onlyGreenBalls)));
    
        }
    

    嗯,
    贝里尔