How to mock local variables in java? [duplicate]

给你一囗甜甜゛ 提交于 2019-12-24 02:14:23

问题


In this situation?

class A {
  public void f() {
    B b = new B();
    C c = new C();
    // use b and c, and how to modify their behaviour?
  }
}

How can I fullfill my idea with PowerMock and EasyMock?

I don't want to change my compact code for test reasons.


回答1:


You can do this, see the answer by Matt Lachman. That approach isn't recommended however. It's a bit hacky.

The best approach would be to delegate creation of your dependant objects to a factory pattern and inject the factories into your A class:

class BFactory {

    public B newInstance() {
        return new B();
    }
}

class CFactory {

    public C newInstance() {
        return new C();
    }
}

class A {

    private final BFactory bFactory;
    private final CFactory cFactory;

    public A(final BFactory bFactory, final CFactory cFactory) {
        this.bFactory = bFactory;
        this.cFactory = cFactory;
    }

    public void f() {
        B b = bFactory.newInstance();
        C c = cFactory.newInstance();
    }
}

You would then mock the factories to return mock instances of the dependent classes.

If for some reason this is not viable then your can create factory methods in the A class

class A {

    public void f() {
        B b = newB();
        C c = newC();
    }

    protected B newB() {
        return new B();
    }

    protected C newC() {
        return newC();
    }
}

Then you can use a spy that mocks those factory methods.




回答2:


You can, in fact, mock object construction using PowerMock. They have great documentation for it right here: https://code.google.com/p/powermock/wiki/MockConstructor

Also take a look at this example which walks through mocking object construction.




回答3:


Whitout changing the code it will not work. (Design for testability). You can replace B with a factory method, that creates B1 in real, or BTest in test, both implementing IB Interface.




回答4:


Looks like you need Dependency Injection.

You are creating concrete instances of B and C, then you cannot modify the behavior.

Pass the instances as an argument to f(InterfaceB b, InterfaceC c), you should make use of polymorphism and then you can pass a mock instance whose behavior you need to change as an argument to this method. So the method does not need to care which type of concrete instance it being passed to it and you can achieve what you need.

I know the names of interfaces are illogical but that could explain the context easily.



来源:https://stackoverflow.com/questions/15895546/how-to-mock-local-variables-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!