Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试中的部分模拟/伪造_C#_Unit Testing_Mocking_Fakeiteasy - Fatal编程技术网

C# 单元测试中的部分模拟/伪造

C# 单元测试中的部分模拟/伪造,c#,unit-testing,mocking,fakeiteasy,C#,Unit Testing,Mocking,Fakeiteasy,我有一个关于假货的问题(或者其他的模拟物品,因为我相信它们非常相似)。以下是我的puesdocode: public class Service { public void CheckService() { ... Status status; if (Getboolean) { status = Status.Pass; } else {

我有一个关于假货的问题(或者其他的模拟物品,因为我相信它们非常相似)。以下是我的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()?如果没有,我应该如何修改代码

谢谢,
凯尔

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

但在你的方法中,我认为你可以不用任何嘲弄。
我希望这有帮助

即使这是可能的,也很可能是个坏主意。单元测试
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语法,对不起,我不知道fakeitesy):

[测试]
带有TrueGetBoolean的公共无效支票服务应具有密码状态
{
//安排
var logicCheckerMock=new Mock();
logicCheckerMock.Setup(x=>x.Getboolean())。返回(true);
var服务=新服务(logicCheckerMock.Object);
//表演
service.CheckService();
//断言
Assert.That(service.Status,Is.EqualTo(Status.Pass));
}
[测试]
带有FalseGetBoolean的公共无效支票服务应具有NotPassStatus
{
//安排
var logicCheckerMock=new Mock();
logicCheckerMock.Setup(x=>x.Getboolean())。返回(false);
var服务=新服务(logicCheckerMock.Object);
//表演
service.CheckService();
//断言
Assert.That(service.Status,Is.EqualTo(Status.NotPass));
}

一般来说,自嘲是一个阶级承担太多责任的标志。更聪明的想法是,为您想要自嘲的不同部分划分其他类,并将这些类注入到您的类中。查找依赖项注入

如果你真的需要这么做,这是可能的。我没有使用FakeiTasy,但在
MOQ
中,您只需将
Mock
属性
CallBase
设置为true即可

自嘲的总体思路是:

你对你的类做了一个“测试”,它扩展了你的类。然后写出测试所需的函数

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

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

然后,您的测试代码将该类用于对象的存根版本。

我同意这一点。您可以模拟无法控制的项,例如数据库的状态。模拟不必用于I/O操作。当单元测试调用另一个对象的方法时,您应该只关心当该对象返回不同的值时,您的方法会做什么。所以你会嘲笑那个对象的方法,因为你没有测试它。是的,当然!我的意思是主要目的,但是当然,您可以模拟这些方法来返回您想要的值,以便只测试您的主要方法。我的意思是,在这种情况下,我认为这是不必要的!;)这与最近提出的问题非常接近,我在其中解释了如何执行您的要求。然而,我仍然和其他人争辩说,这可能不是一个好主意。布莱尔·康拉德,非常接近!谢谢你的信息。(我想在发布之前,我必须更努力地搜索类似的内容!!)。
public class TestServiceThatAlwaysReturnFalseForCheckBoolean : Service
{
    public void CheckService()
    {
        base.CheckService()
    }

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