简体   繁体   English

Mockito:模拟类始终调用真实方法

[英]Mockito: mocking class always calls real method

I would like to mock a class. 我想模拟一堂课。

The class is called like this: 该类的调用如下:

here's my code: 这是我的代码:

@Mock
SomeClass someClass;

@InjectMocks
ToBeTested toBeTested;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

// in the test:
doReturn(returnValue).when(someClass).doSomething(param1, param2); 

I feel like I have tried every possible combination of @Mock and @Spy and doReturn and when , but instead of mocking the method call, the real method is called and an NPE is thrown. 我觉得我已经尝试了@Mock@Spy以及doReturnwhen所有可能组合,但是不是doReturn方法调用,而是调用了真正的方法并抛出了NPE。

How do I do this correctly? 如何正确执行此操作?

I'll provide more code if needed. 如果需要,我将提供更多代码。

EDIT 编辑

both SomeClass and doSomething() are public and neither are final. SomeClassdoSomething()都是公共的,都不是最终的。

I tried using MockitoJunitRunnerclass instead of MockitoAnnotations and the exception is still thrown. 我尝试使用MockitoJunitRunnerclass代替MockitoAnnotations ,但仍引发异常。

The class to be tested: 要测试的类:

@Component
public class ToBeTested implements Something {

    @Override
    public ReturnValue doSomeAction(Parameter theParam) {
        try {
            SomeClass theClass = new SomeClass();
            MyReturnValue myReturnValue = theClass.doSomething(
                    parameterOfTypeInputStream,
                    parameterOfTypeString
            );

        // other stuff

            return theParam;
        } catch (IOException e) {
            throw new RuntimeException("Oh no!");
        }
    }

// more

param1 and param2 are of type InputStream and String respectively. param1param2分别为InputStream和String类型。

Of course it's not mocked, the actual code create the real class in the method doSomeAction , in order to have the mock injected SomeClass theClass should be a field. 当然,它不是模拟的,实际的代码在doSomeAction方法中创建真实的类,以便将模拟注入SomeClass theClass应该是一个字段。

@Component
public class ToBeTested implements Something {
    SomeClass theClass;

    @Autowired
    public ToBeTested(SomeClass theClass) {
        this.theClass = theClass;
    }    

    @Override
    public ReturnValue doSomeAction(Parameter theParam) {
        try {
            MyReturnValue myReturnValue = theClass.doSomething(
                    parameterOfTypeInputStream,
                    parameterOfTypeString
            );

        // other stuff

            return theParam;
        } catch (IOException e) {
            throw new RuntimeException("Oh no!");
        }
    }

You application container (Spring) should create the bean SomeClass and inject it as this constructor is annotated by @Autowired . 您的应用程序容器(Spring)应该创建bean SomeClass并将其注入,因为此构造函数由@Autowired注释。

And since Mockito's @InjectMocks annotation will look up constructors, it will find this constructor and inject the mock you declared in your test class ( @Mock SomeClass someClass; ). 而且由于Mockito的@InjectMocks批注将查找构造函数,因此它将找到该构造函数并注入您在测试类( @Mock SomeClass someClass; )中声明的模拟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM