当前位置:  开发笔记 > 编程语言 > 正文

模拟方法的结果

如何解决《模拟方法的结果》经验,为你挑选了2个好方法。

我试图找到一种方法来伪造从另一个方法中调用的方法的结果.

我有一个"LoadData"方法,它调用一个单独的帮助器来获取一些数据然后它将转换它(我有兴趣测试转换后的结果).

所以我有这样的代码:

public class MyClass(){
  public void LoadData(){
    SomeProperty = Helper.GetSomeData();
 }
 public object SomeProperty {get;set;}
}

我想从Helper.GetSomeData()方法获得已知结果.我可以使用一个模拟框架(我对Rhino Mocks的经验相当有限,但我愿意接受任何事情)来强制实现预期的结果吗?如果是这样,怎么样?

*编辑 - 是的,如我所料,我无法实现我想要的黑客攻击,我将不得不找到一种更好的方法来设置数据.



1> Marcio Aguia..:

你有问题.我不知道这是否是您的代码的简化方案,但如果以这种方式使用Helper类,那么您的代码是不可测试的.首先,直接使用Helper类,因此不能用mock替换它.其次,您正在调用静态方法.我不知道C#,但在Java中你无法覆盖静态方法.

您将不得不进行一些重构,以便能够使用虚拟GetSomeData()方法注入模拟对象.

在这个简化版本的代码很难给你一个直接的答案.你有一些选择:

为Helper类创建一个接口,并为客户端提供一种将Helper实现注入MyClass类的方法.但是,如果Helper真的是一个实用类,那就没有多大意义了.

在MyClass中创建一个名为getSomeData的受保护方法,并使其仅调用Helper.LoadSomeData.然后将对LoadData中的Helper.LoadSomeData的调用替换为getSomeData.现在,您可以模拟getSomeData方法以返回虚拟值.


谨防简单地创建Helper类的接口并通过方法注入它.这可以暴露实现细节.为什么客户端应该提供实用程序类的实现来调用简单的操作?这将增加MyClass客户端的复杂性.



2> Justin Bozon..:

我建议将你拥有的东西转换成这样的东西:

public class MyClass()
{
    private IHelper _helper;

    public MyClass()
    {
        //Default constructor normal code would use.
        this._helper = new Helper();
    }

    public MyClass(IHelper helper)
    {
        if(helper == null)
        {
            throw new NullException(); //I forget the exact name but you get my drift ;)
        }
        this._helper = helper;
    }

    public void LoadData()
    {
        SomeProperty = this._helper.GetSomeData();
    }
    public object SomeProperty {get;set;}
}

现在,您的类支持所谓的依赖注入.这允许您注入辅助类的实现,并确保您的类只需要依赖于接口.当你嘲笑这个时,你就知道你只需要创建一个使用IHelper接口并将其传递给构造函数的模拟器,你的类将使用它,就像它是真正的Helper类一样.

现在,如果您坚持使用Helper类作为静态类,那么我建议您使用代理/适配器模式并将静态类包装为另一个支持IHelper接口的类(您还需要创建).

如果您希望在某个时候更进一步,可以从修订的类中完全删除默认的Helper实现,并使用IoC(Inversion of Control)容器.如果thiis对你来说是新的,我会建议首先关注为什么所有这些额外的麻烦值得的基础(这是恕我直言).

您的单元测试看起来像这样的伪代码:

public Amazing_Mocking_Test()
{
    //Mock object setup
    MockObject mockery = new MockObject();
    IHelper myMock = (IHelper)mockery.createMockObject();
    mockery.On(myMock).Expect("GetSomeData").WithNoArguments().Return(Anything);

    //The actual test
    MyClass testClass = new MyClass(myMock);
    testClass.LoadData();

    //Ensure the mock had all of it's expectations met.
    mockery.VerifyExpectations();
}

如果您有任何疑问,请随时发表评论.(顺便说一句,我不知道这个代码是否全部可行,我只是在浏览器中输入它,我主要是说明这些概念).

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有