0

サービスがあるとしましょう

public interface IAreaService
{
   int CalculateArea(int x,int y);
   int CalculateAreaTimesX(int x, int y, int ammount);
}

public class AreaService : IAreaService
{
    public int CalculateArea(int x,int y)
    {
        return x*y;
    }

    public int CalculateAreaTimesX(int x, int y, int ammount)
    {
        return CalculateArea(x, y)*ammount;
    }
}

関連する単体テストを使用

[TestMethod]
    public void AreaService_GetArea_Test()
    {
        AreaService service = new AreaService();
        int expected = 9;
        int actual  = service.CalculateArea(3, 3);
        Assert.AreEqual(expected,actual,"The Calculate area does not work as expected");
    }

    [TestMethod]
    public void AreaService_GetAreaMultiplyByX_TestTrueValue()
    {
        AreaService service = new AreaService();
        int expected = 27;
        int actual = service.CalculateAreaTimesX(3, 3, 3);
        Assert.AreEqual(expected,actual);
    }

ユニットテストを実行した後です。問題の私の方法が機能していると確信しており、人生は素晴らしいものになるはずです.

しかし今、私は別のクラスで IAreaService を使用したいと思っています。これは私が光を失う場所です。これが他のクラスの実装です。

public class PriceCalculatorService
{
    private readonly IAreaService _areaService;
    public PriceCalculatorService(IAreaService areaService)
    {
        _areaService = areaService;
    }


    public double GetPrice(int x, int y, int times, double price)
    {
       return  _areaService.CalculateAreaTimesX(x, y, times)*price;
    }
}

次の単体テストを実行した場合 (ここでモックするのは私の考えが間違っている可能性があり、ここで問題が発生します。

[TestMethod]
    public void PriceCalculatorService_GetPrice_Test()
    {
        var IAreaServiceMock = new Mock<IAreaService>();
        IAreaServiceMock.Setup(ism => ism.CalculateAreaTimesX(2, 2, 2)).Returns(8);
        PriceCalculatorService priceCalc = new PriceCalculatorService(IAreaServiceMock.Object);

        double expected = 20;
        double actual = priceCalc.GetPrice(2, 2, 2, 2.50);
        Assert.AreEqual(expected,actual);
    }

質問

上記の単体テストをすべて実行すると、すべて問題ありません。それらのすべてが合格します。しかし、何らかの理由で AreaService.Calculate() メソッドを次のように変更する必要があるとしましょう

public int CalculateArea(int x,int y)
{
    return x*y+2;
}

これは、私のユニット テスト "AreaService_GetArea_Test()" が本来のように失敗することを意味しますが、"PriceCalculatorService_GetPrice_Test()" テストで使用されるモッキングのために、サービスをモックすると実際のコードは使用されていません(明らかに)。したがって、私の PriceCalculatorService_GetPrice_Test は役に立ちません。しかし、スタブを使用すると、単体テストは失敗するはずです。

では、いつ Mock を使用し、いつ Mock を使用しないのでしょうか?

4

2 に答える 2

4

したがって、私の PriceCalculatorService_GetPrice_Test は役に立ちません。

いいえ、ちがいます。のコードをテストしており、 のコードGetPriceのみをテストGetPriceしています。私には合理的に思えます。

そのメソッドでテストすることはあまりありませんが、テストしています。同じ引数が 3 回ない方がよいでしょう (たとえば、1、2、3 を使用した方がよいでしょう) が、それをテストしています。

インターフェイスの実装が変更されたからといって、そのテストが壊れる理由はありません。AreaServiceinへの変更をキャッチしましたAreaService_GetArea_Test()。これは、実際にキャッチする必要がある場所です。

于 2012-08-21T21:23:34.390 に答える
2

PriceCalculatorService_GetPrice_Testテスト中GetPriceです。の戻り値GetPrice_areaService.CalculateAreaTimesX(x, y, times)乗算されているかどうかをテストしていpriceます。それが試験の意味です。だから全然駄目じゃない。

GetPriceCalculateAreaTimesXそのメソッドのロジックではなく、の結果に依存する必要があります。したがって、モックが何を返しても、テストには問題ありません。

于 2012-08-22T06:19:26.850 に答える