Java 假装没有被注射
我试图为单元测试注入一个mock,但我一直得到一个null点异常 下面是我要测试的类,空指针似乎带有ParameterFacade 当我运行测试时,它似乎没有注入mock,因为参数facade为nullJava 假装没有被注射,java,junit,mockito,Java,Junit,Mockito,我试图为单元测试注入一个mock,但我一直得到一个null点异常 下面是我要测试的类,空指针似乎带有ParameterFacade 当我运行测试时,它似乎没有注入mock,因为参数facade为null @Service public class PostUnderwriterTransactionProcessProvider extends AbstractProcessProvider<PostUnderwriterTransactionInput> { @Autow
@Service
public class PostUnderwriterTransactionProcessProvider extends AbstractProcessProvider<PostUnderwriterTransactionInput> {
@Autowired
private ParameterFacade parameterService;
@Override
public Page startProcess(PostUnderwriterTransactionInput processInput) {
final PostUnderwriterTransactionContext context = new PostUnderwriterTransactionContext(processInput.getPolicy(),
setupStrataContextModel(POST_TRANSACTIONS),
processInput.getTransactionsTypes(),
processInput.getParameterSelectionCriteria(),
parameterService.shouldApplyCommissionFromPolicy());
context.setPostingFromInput(processInput.getAccount().getBalance(),
processInput.getAccount().getID(),
getBranch(),
processInput.getPolicy(),
processInput.getProcess(),
null);
return new AdhocTransactionPostingPage(new TransactionPostingContextModel(context));
}
}
@服务
公共类postenderWriterTransactionProcessProvider扩展了AbstractProcessProvider{
@自动连线
私有参数facade参数服务;
@凌驾
公共页面启动进程(PostanderWriterTransactionInputProcessInput){
final postenderWriterTransactionContext=新的postenderWriterTransactionContext(processInput.getPolicy(),
setupStrataContextModel(后交易),
processInput.getTransactionsTypes(),
processInput.getParameterSelectionCriteria(),
parameterService.shouldApplyCommissionFromPolicy());
context.setPostingFromInput(processInput.getAccount().getBalance(),
processInput.getAccount().getID(),
getBranch(),
processInput.getPolicy(),
processInput.getProcess(),
无效);
返回新的AdhocTransactionPostingPage(新的TransactionPostingContextModel(上下文));
}
}
测试是
@RunWith(MockitoJUnitRunner.class)
public class PostUnderwriterTransactionProcessProviderTest extends WicketTestCase {
@ClassRule
public static MetadataServiceRule metadataServiceRule = new MetadataServiceRule();
@Mock
private ParameterFacade mockParameterService;
@InjectMocks
private PostUnderwriterTransactionProcessProvider testSubject;
@Before
public void setup() {
tester.putBean(mockConversationScopeManager);
testSubject = new PostUnderwriterTransactionProcessProvider();
policy = PolicyTestDataBuilder.aPolicy().build();
account = createAccount();
testSubject.setUserInfoProvider(MockUserInfoPartyProvider.getMockUserInfoProvider());
testSubject.setSystemPartyFacade(MockUserInfoPartyProvider.getMockSystemPartyFacade());
testSubject.setCodeModelFacade(codeModelFacade);
}
@Test
public void startProcessShouldCreateAdhocTransactionPostingPage() {
// Given
when(mockParameterService.shouldApplyCommissionFromPolicy()).thenReturn(true);
final ParameterSelectionCriteriaModel pscm = new ParameterSelectionCriteriaModel();
final List<TransactionTypeModel> transactions = createTransactionsTypes();
final PostUnderwriterTransactionInput input = new PostUnderwriterTransactionInput(policy, account, pscm, transactions);
// When
final Page page = testSubject.startProcess(input);
// Then
assertThat(page, instanceOf(AdhocTransactionPostingPage.class));
assertThat("Page Default Model is: ", page.getDefaultModelObject(), instanceOf(PostUnderwriterTransactionContext.class));
assertPageContextValues(page);
}
}
@RunWith(MockitoJUnitRunner.class)
公共类postenderWriterTransactionProcessProviderTest扩展了WicketTestCase{
@阶级规则
公共静态MetadataServiceRule MetadataServiceRule=新MetadataServiceRule();
@嘲弄
私有参数服务;
@注射模拟
私有postenderWriterTransactionProcessProviderTestSubject;
@以前
公共作废设置(){
putBean(mockConversationScopeManager);
testSubject=new postenderWriterTransactionProcessProvider();
policy=PolicyTestDataBuilder.aPolicy().build();
account=createAccount();
testSubject.setUserInfoProvider(MockUserInfoPartyProvider.getMockUserInfoProvider());
testSubject.setSystemPartyFacade(MockUserInfoPartyProvider.getMockSystemPartyFacade());
setCodeModelFacade(codeModelFacade);
}
@试验
public void startProcess应创建AdhocTransactionPostingPage(){
//给定
when(mockParameterService.shouldApplyCommissionFromPolicy())。然后返回(true);
最终参数SelectionCriteriaModel pscm=新参数SelectionCriteriaModel();
最终列表事务=createTransactionsTypes();
final postenderWriterTransactionInput=新的postenderWriterTransactionInput(策略、账户、pscm、交易);
//什么时候
最终页面=testSubject.startProcess(输入);
//然后
断言(第页,instanceOf(AdhocTransactionPostingPage.class));
断言(“页面默认模型为:”,Page.getDefaultModelObject(),instanceOf(postenderWriterTransactionContext.class));
assertPageContextValues(第页);
}
}
线路
testSubject = new PostUnderwriterTransactionProcessProvider();
正在重写用创建的实例
@InjectMocks
private PostUnderwriterTransactionProcessProvider testSubject;
删除手动初始化以使框架按设计运行
否则,如果您想手动注入依赖项,则考虑重构类遵循显式依赖原则
@Service
public class PostUnderwriterTransactionProcessProvider
extends AbstractProcessProvider<PostUnderwriterTransactionInput> {
private final ParameterFacade parameterService;
@Autowired
public PostUnderwriterTransactionProcessProvider(ParameterFacade parameterService) {
this.parameterService = parameterService;
}
//...omitted for brevity
}
看看下面的代码,让我们看看每一行都做了什么-
@Mock
private ParameterFacade mockParameterService; //1
@InjectMocks
private PostUnderwriterTransactionProcessProvider testSubject; // 2
@Before
public void setup() {
testSubject = new PostUnderwriterTransactionProcessProvider(); //3
}
行1
使用spring框架的@Mock
注释。这告诉spring模拟类型为ParameterFacade
的对象,创建一个模拟的实例,并将其保存在mockParameterService
变量中
行2
使用@InjectMocks
注释,该注释告诉spring使用在该测试中创建的模拟对象(我们在行1
中创建了该对象),并在创建它时将其用作变量testSubject
中的依赖项。这将导致testSubject
包含postenderWriterTransactionProcessProvider
的实例,该实例的依赖项为模拟类型ParameterFacade
注入到他身上
第
3行
创建了postenderWriterTransactionProcessProvider的新实例
。这是纯java,没有spring,没有模拟,没有依赖。只需按照java的常规方式创建该类型的新实例。在2
中创建的实例被这个新的普通实例替换,并且在某种程度上,任何断言都会覆盖以前的值,这使得变量testSubject
保存这个对象对提供的答案有任何反馈吗?
1. ParameterFacade is a spring container managed bean (as it is annotated with @Service and other spring annotations like @Autowired).
2. @RunWith is configured to use MockitoJUnitRunner which cannot instantiate spring managed container beans
Hence, in order to handle bean lifecycle in unit tests you'll need to
1. Use @RunWith(SpringJUnit4ClassRunner.class)
2. Annotate PostUnderwriterTransactionProcessProvider with @Autowired.
3. Change @Mock to @MockBean on ParameterFacade (org.springframework.boot.test.mock.mockito.MockBean)
@Mock
private ParameterFacade mockParameterService; //1
@InjectMocks
private PostUnderwriterTransactionProcessProvider testSubject; // 2
@Before
public void setup() {
testSubject = new PostUnderwriterTransactionProcessProvider(); //3
}