3

FakeItEasy (または、かなり似ていると思われる他のモック オブジェクト) について質問があります。以下は私のpuesdocodeです:

public class Service
{
    public void CheckService()
    {
        ...
        Status status;

        if (Getboolean)
        {
            status = Status.Pass;
        }
        else
        {
            status = Status.NotPass;
        }
    }

    public bool Getboolean()
    {
        .....

        if (someConditions)
            return true;
        else
            return false;
    }
}

public enum Status
{
    Pass = 0,
    NotPass = 1
}

ここで、クラスの単体テスト コードを作成する必要があります。baseMethod() で Checkservice() を実際にテストしているときに GetBoolean() をモックすることは可能ですか? そうでない場合、コードをどのように変更すればよいですか?

ありがとう、カイル

4

3 に答える 3

3

たとえそれが可能だったとしても、それはおそらく悪い考えです。単体テストは、テストではなく、CheckServiceテストCheckServiceのみを行う必要がありますGetbooleanGetboolean他の方法に依存しない個別の単体テストが必要です。

それを行う正しい方法はGetboolean、インターフェースから継承する別のクラスにあなたを持ち、そのインターフェースをServiceコンストラクターに渡し(おそらく依存性注入を使用して)、次にそのインターフェースをモックして、ユニットにモック実装を渡すことができますテスト。

例:

public interface ILogicChecker
{
    bool Getboolean();
}

public class LogicChecker : ILogicChecker
{
    public bool Getboolean()
    {
        //.....

        if (someConditions)
            return true;
        else
            return false;
    }
}

public class Service
{
    ILogicChecker logicChecker;
    Status status;

    public Service(ILogicChecker logicChecker)
    {
        this.logicChecker = logicChecker;
    }

    public void CheckService()
    {
        //...

        if (logicChecker.Getboolean())
        {
            status = Status.Pass;
        }
        else
        {
            status = Status.NotPass;
        }
    }
}

public enum Status
{
    Pass = 0,
    NotPass = 1
}

次に、テスト クラスで (Moq 構文を使用します。申し訳ありませんが、FakeItEasy はわかりません):

[Test]
public void CheckService_WithTrueGetboolean_ShouldHave_PassStatus
{
    //Arrange
    var logicCheckerMock = new Mock<ILogicChecker>();
    logicCheckerMock.Setup(x => x.Getboolean()).Returns(true);
    var service = new Service(logicCheckerMock.Object);

    //Act
    service.CheckService();

    //Assert
    Assert.That(service.Status, Is.EqualTo(Status.Pass));
}

[Test]
public void CheckService_WithFalseGetboolean_ShouldHave_NotPassStatus
{
    //Arrange
    var logicCheckerMock = new Mock<ILogicChecker>();
    logicCheckerMock.Setup(x => x.Getboolean()).Returns(false);
    var service = new Service(logicCheckerMock.Object);

    //Act
    service.CheckService();

    //Assert
    Assert.That(service.Status, Is.EqualTo(Status.NotPass));
}
于 2014-02-27T22:44:56.440 に答える
2

一般的Self Mockingに、責任を負いすぎるクラスの兆候です。よりスマートなアイデアは、セルフモックしたいさまざまな部分の他のクラスを分割し、それらのクラスを自分のクラスに注入することです。見上げるdependency injection

ただし、本当にそれを行う必要がある場合は、可能です。私は FakeItEasy を使用していませんが、プロパティを true に設定してMOQを作成するだけです。Mock<YourClass>CallBase

ただし、セルフモックの一般的な考え方は次のとおりです。

クラスを拡張するクラスの「テスト」バージョンを作成します。そして、テストに必要な機能を詰め込みます。

public class TestServiceThatAlwaysReturnFalseForCheckBoolean : Service
{
    public void CheckService()
    {
        base.CheckService()
    }

    public override bool Getboolean()
    {
        return false;
    }
}

次に、テスト コードはそのクラスをオブジェクトのスタブ バージョンに使用します。

于 2014-02-27T23:00:25.387 に答える