简体   繁体   中英

Unit test not using derived object

I'm attempting to test a function that implements several dice tables. I've derived a formula, and I'm currently writing a set of test cases to test normal operation, and then the two logic cases to prevent out of bounds results.

The function being tested is

    public static int getNumberOfStars(Dice ourDice, int mod = 0)
    {
        int roll = ourDice.gurpsRoll() + mod;
        int numStars = (int)(Math.Floor((roll - 1.0) / 5.0));

        //fix a few possible logic bugs.
        if (numStars < 1) numStars = 1;
        else if (numStars > 3) numStars = 3;
        return numStars;           
    }

Dice is an object that acts as an interface with a PRNG. The function in question rolls 3d6. The mock object is:

    public class FakeDice : Dice
    {
          public int diceRoll;

          public new int gurpsRoll()
         {
             return diceRoll;
         }

      ...
  }

and finally, the test case is

    [TestMethod]
    public void VerifyMaxNumberOfStars()
    {
        FakeDice ourDice = new FakeDice();
        ourDice.diceRoll = 18;
        int numDice = StarReference.getNumberOfStars(ourDice, 3);
        Assert.AreEqual(3, numDice);
    }

The results alter between runs, leading me to believe it's not using the new function, and instead the base one. (This test has never ran, but manually running the code shows it returns a valid result.)

What am I doing wrong?

Your FakeDice class is not overriding the gurpsRoll() method, it is hiding it.

To override the implementation you would need to declare gurpsRoll as virtual in the Dice class, and you would need to use the override keyword in your FakeDice class.

You can find more details on this behavior on MSDN here http://msdn.microsoft.com/en-us/library/ms173153.aspx

That's because new methods do not override their base methods.

new methods are only called when dealing with the class they're declared in. If you're using polymorphism, the base method will be called instead

Here's an example:

FakeDice fake = new FakeDice();
fake.gurpsRoll();  // calls FakeDice's implementation

Dice dice = fake;
dice.gurpsRoll();  // calls Dice's implementation

You need to make the base method virtual and then override it.

See:

When overriding a method with the new keyword, it will only execute when boxing the object as the derived object. You need to make the method you want to override virtual, like so:

public class FakeDice : Dice
{
      public int diceRoll;

      public override int gurpsRoll()
     {
         return diceRoll;
     }

  ...
}

public class Dice 
{
    public virtual int gurpsRoll() {...}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM