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

我认为这里没有什么可模拟的。在我看来,Mock 的主要目的是,例如,如果您必须连接到数据库,那么您可以模拟存储库并返回您想要的数据,而无需连接到数据库。

但在你的方法中,我认为你可以在没有任何 Mock 的情况下做到这一点。我希望这有帮助!

于 2014-02-27T22:42:59.900 回答
3

好吧,即使这是可能的,也很可能是个坏主意。单元测试CheckService应该只是测试CheckService,而不是Getboolean. 应该有一个单独的单元测试,Getboolean它不依赖于任何其他方法。

正确的方法是让你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,但在MOQ您中只需将Mock<YourClass>属性CallBase设置为 true。

自我嘲讽的总体思路是这样的:

你对你的班级做了一个“测试”版本,它扩展了你的班级。然后找出你想要的测试功能。

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

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

那么您的测试代码将使用该类作为对象的存根版本。

于 2014-02-27T23:00:25.387 回答