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_Fakeiteasy - Fatal编程技术网

C# 在一个方法中模仿一个方法

C# 在一个方法中模仿一个方法,c#,unit-testing,fakeiteasy,C#,Unit Testing,Fakeiteasy,如何模拟/复制在另一个函数中调用的函数的结果?通常Test2是一种我不喜欢获取真实数据的数据访问方法。 我喜欢我的unittest测试的是业务逻辑 [TestMethod()] public void TestToTest() { //Arrange var instance = A.Fake<IClassWithMethods>(); //Make calling Test2 return 5 and not 10. A.CallTo(() => instanc

如何模拟/复制在另一个函数中调用的函数的结果?通常Test2是一种我不喜欢获取真实数据的数据访问方法。 我喜欢我的unittest测试的是业务逻辑

[TestMethod()]
public void TestToTest()
{
//Arrange
var instance = A.Fake<IClassWithMethods>();

      //Make calling Test2 return 5 and not 10.
A.CallTo(() => instance.Test2()).Returns(5);

      //Call the method 
var sum = instance.Test1();

//Assert if the business logic in the method works.
Assert.AreEqual(15, sum);
}
这就是我现在拥有的,但它根本不起作用。总和总是断言为5

public int Test1()
{
    var value = this.Test2(); //Unittest should substitute with 5
    var businesslogic = value + 10; //The business logic

    return businesslogic;
}

public int Test2()
{
    return 10; //I try to mock this value away in the test. Don´t go here!
}
然后我有一个单元测试,我想在我的“业务逻辑”上运行它

[TestMethod()]
公共void TestToTest()
{
//安排
var实例=A.Fake();
//使调用Test2返回5而不是10。
A.CallTo(()=>instance.Test2()).Returns(5);
//调用该方法
var sum=instance.Test1();
//断言方法中的业务逻辑是否有效。
断言:相等(15,总和);
}

据我所知,你不能那样做

您的
实例
不是真实类的实例,只是它接口上的一个模型,因此调用
实例.Test1()
不会调用上面描述的代码。但是,您可以自己使用UnitTest
Test2
方法

但是,您可以做的是进行2个单元测试

在第一个测试(测试方法
Test2
)中,您使用必要的依赖项(或者如果没有具有特定值/参数的依赖项)实例化类

然后使用相同的输入参数进行第二次测试,并测试
test()
方法


实体模型仅用于必须在接口上进行实体模型的依赖项(该接口在测试类的外部实例化)。i、 e.如果您有
ClassA
ClassB
ClassA
取决于
IClassB
接口。然后你可以模拟B来测试A。

首先,让我说,我认为中有一些奇妙的点,特别是关于如何

  • 伪造接口意味着永远不能调用“内部方法”,并且
  • 您应该伪造依赖项,而不是内部。如果你可以选择做这个改变,现在就做吧,停止阅读我的答案
  • 如果你还在读书,我对两件事感到困惑:

  • 是否应
    Test1
    返回
    businessLogic
    ?正如所写的那样(一旦编译错误被修复),当
    Test2
    返回5时,我希望
    Test1
    返回5(而不是15)
  • TestToTest
    中,当您在
    Test2
    上设置
    返回(5)
    ,然后调用
    Test1
    时,由于您伪造了一个接口,我希望sum为0,int的默认值。我不确定如何得到5。事实上,我在这次测试中复制了这种行为:


  • 回答得很好。我修正了问题中的代码来回答你的第一个问题。但是不管这个确切的例子是什么,我真正想做的是能够在一个方法中测试逻辑,而不调用在其中调用的其他方法。比如,如果我在Test2中向数据库中插入了一些内容,我不想调用该方法,但我希望能够测试该方法的“value+10”部分的业务逻辑。我同意我不喜欢虚拟解决方案,改变方法似乎太激烈了。如果你不想改变任何方法,那么我不知道你将如何完成你想要的测试。我和曾荫权的建议都需要对代码进行一些修改,曾荫权的建议更具戏剧性(我认为更优越)。我认为你需要使用一个模拟框架,比如或者如果你想避免修改你的代码的话。非常感谢。Microsoft Fakes正是我搜索的对象。这里有一个开始使用它的好链接
    [TestMethod]
    public void TestToTestInterface()
    {
        //Arrange
    
        var instance = A.Fake<IClassWithMethods>();
    
        //Make calling Test2 return 5 and not 10.
        A.CallTo(() => instance.Test2()).Returns(5);
    
        //Call the method 
        var sum = instance.Test1();
    
        //Assert if the business logic in the method works.
        Assert.AreEqual(0, sum); // because Test1 wasn't faked
    }
    
    public class ClassWithMethods : IClassWithMethods
    {
        public virtual int Test1()
        {
            var value = this.Test2(); //Unittest should substitute with 5
            var businesslogic = value + 10; //The business logic
    
            return businesslogic;
        }
    
        public virtual int Test2()
        {
            return 10; //I try to mock this value away in the test. Don´t go here!
        }
    }
    
    [TestMethod]
    public void TestToTestClass()
    {
        //Arrange
    
        var instance = A.Fake<ClassWithMethods>();
    
        //Make calling Test2 return 5 and not 10.
        A.CallTo(() => instance.Test2()).Returns(5);
    
        // Make sure that Test1 on our fake calls the original ClassWithMethods.Test1
        A.CallTo(() => instance.Test1()).CallsBaseMethod();
    
        //Call the method 
        var sum = instance.Test1();
    
        //Assert if the business logic in the method works.
        Assert.AreEqual(15, sum);
    }