【问题标题】:Getting NullPointerException in my mock dependence在我的模拟依赖中获取 NullPointerException
【发布时间】:2016-06-16 21:32:59
【问题描述】:

我有这个测试:

@RunWith(MockitoJUnitRunner.class)
public class MainClassTest {

@Mock
Dependence dependence;

@InjectMocks
MainClass mainClassTester;

}

还有这个测试:

  @Test
    public void testA() {
    when(dependence.getStatus()).thenReturn(true);
    mainClassTester.startStatusOperation(); 

    }

我的 MainClass 类看起来像:

public class MainClass{

 private Dependence dependence = new Dependence() ;

 public boolean startStatusOperation(){
   boolean status = dependence.getStatus();
   [...]
 }
}

我在这一行得到 NullPointer:

boolean status = dependence.getStatus();

为什么模拟“依赖”不起作用?当我使用@inject 时,这段代码总是有效,但不能在这个中使用。

【问题讨论】:

  • 你的 MainClass 有构造函数吗?
  • 如果您需要任何帮助,您将不得不发布完整的堆栈跟踪。

标签: java junit mockito


【解决方案1】:

如果你想使用构造函数而不是@Inject来创建对象,你需要模拟构造函数而不是仅仅使用@Mock。

@InjectMock 只会注入 @Inject 使用的字段。如果您有任何由新构造函数设置的字段,则如果您使用@InjectMock,则不会将其注入测试对象。 来自http://site.mockito.org/mockito/docs/current/org/mockito/InjectMocks.html

@Documented
@Target(value=FIELD)
@Retention(value=RUNTIME)
public @interface InjectMocks
Mark a field on which injection should be performed.
Allows shorthand mock and spy injection.
Minimizes repetitive mock and spy injection.
Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.

Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. If the object is successfully created with the constructor, then Mockito won't try the other strategies. Mockito has decided to no corrupt an object if it has a parametered constructor.
Note: If arguments can not be found, then null is passed. If non-mockable types are wanted, then constructor injection won't happen. In these cases, you will have to satisfy dependencies yourself.

Property setter injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the property name and the mock name.
Note 1: If you have properties with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won't happen.

Note 2: If @InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.

Field injection; mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the field name and the mock name.
Note 1: If you have fields with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching fields, otherwise Mockito might get confused and injection won't happen.

Note 2: If @InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.

【讨论】:

  • 就是这样,没有@injects 我不能使用injectMocks,我需要一个构造函数来设置我的属性或setter 方法。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 2015-12-21
  • 1970-01-01
相关资源
最近更新 更多