简体   繁体   English

抛出Mockito NullPointerException而不是自定义ExitException

[英]Mockito NullPointerException thrown instead of custom ExitException

I'm trying to test the functionality of my ApplicationRunner class which currently depends on a simple CLI class. 我正在尝试测试ApplicationRunner类的功能,该类当前依赖于简单的CLI类。 Using mockito, i'm attempting to mock the CLI and determine the conditions on which a custom ExitException is thrown. 我正在尝试使用ExitException模拟CLI并确定引发自定义ExitException的条件。 (when the CLI s help() method is shown). (显示CLIhelp()方法时)。 My issue is that the test is throwing a NullPointerException rather than an ExitException when it his the parse function. 我的问题是,测试在parse函数时会抛出NullPointerException而不是ExitException

Test code: 测试代码:

public class ApplicationRunnerTest {

@Mock
private APUCLI cli;

private ApplicationRunner runner;

@Before
public void prepareDependencies(){
    MockitoAnnotations.initMocks(this);
    runner = new ApplicationRunner();
}


@Test(expected = ExitException.class)
public void verifyHelpOptionsRun() throws Exception{
    String[] args = new String[]{};

    runner.run(args);

    when(cli.parse(args)).thenReturn(null);

    verify(cli, times(1)).parse(args);
    verify(cli, times(1)).help();
}

}

The cli class which is mocked: cli类被嘲笑:

@Component("Cli")
public class APUCLI implements CLI {


@Override
public ParsedArgs parse(String args[]) {
    System.out.println("Parsing CLI");
    return null;
}

@Override
public void help() throws ExitException{
    System.out.println("something");
    throw new ExitException(1);
}
}

The APU Runner code. APU运行程序代码。

@Component("Runner")
public class ApplicationRunner implements APURunner{

@Inject
@Named("Cli")
private CLI commandLineInterface;

@Override
public void run(String[] args) throws ExitException{
    ParsedArgs parsedArgs = getParsedArgs(args);
    if(parsedArgs == null){
        callHelp();
    }

    System.out.println("Running");

}

private ParsedArgs getParsedArgs(String[] args){
    return commandLineInterface.parse(args);
}

private void callHelp() throws ExitException{
    commandLineInterface.help();
}
}

The error: 错误:

java.lang.Exception: Unexpected exception, expected<Systems.biology.laboratory.ExitException> but was<java.lang.NullPointerException>

at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NullPointerException
at Systems.biology.laboratory.runners.ApplicationRunner.getParsedArgs(ApplicationRunner.java:33)
at Systems.biology.laboratory.runners.ApplicationRunner.run(ApplicationRunner.java:23)
at Systems.biology.laboratory.runners.ApplicationRunnerTest.verifyHelpOptionsRun(ApplicationRunnerTest.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
... 15 more

You have two issues (at least) : 您有两个问题(至少):

1) You mock a APUCLI instance : 1)您模拟一个APUCLI实例:

@Mock
private APUCLI cli;

But you never set it to the ApplicationRununer instance under test. 但是您永远不会将其设置为受测试的ApplicationRununer实例。 So the APUCLI field defined in the ApplicationRununer instance is null . 因此,在ApplicationRununer实例中定义的APUCLI字段为null

You could provide a constructor that allows to set the dependency. 您可以提供一个允许设置依赖项的构造函数。

So you could replace : 因此,您可以替换:

@Inject
@Named("Cli")
private CLI commandLineInterface;

by : 创建人:

private CLI commandLineInterface;

@Inject
public ApplicationRunner(CLI commandLineInterface){
     this.commandLineInterface = commandLineInterface;
}

You could so create it in this way : 您可以这样创建它:

@Before
public void prepareDependencies(){
    MockitoAnnotations.initMocks(this);
    runner = new ApplicationRunner(cli);
}

About the @Named qualifier, sorry I am not sure about the way to specify it in a autowired constructor with a javax Inject annotation. 关于@Named限定词,很抱歉,我不确定在带有javax Inject注释的自动装配构造函数中指定它的方式。
So I prefer put this point aside. 因此,我宁愿将这一点放在一边。

2) You set the mock behavior after executing the method to test. 2)在执行要测试的方法后,设置模拟行为。 It is too late.It should be done before if you want that it be considered during the execution of the method to test. 为时已晚,如果要在执行测试方法时考虑它,则应在完成之前进行。

@Test(expected = ExitException.class)
public void verifyHelpOptionsRun() throws Exception{
    String[] args = new String[]{};

    // mock record first
    when(cli.parse(args)).thenReturn(null); 

    // execute the method to test
    runner.run(args);        

    // do some checks (if required)
    verify(cli, times(1)).parse(args);
    verify(cli, times(1)).help();
}

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

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