这是我的代码的一个非常简化的版本,它说明了具体的问题。
有什么方法可以控制从测试中调用accountProductRepository.refresh()时会发生什么?
不知何故,我需要在buyProduct()方法中创建的AccountProductPojo上设置ProductPojo,因此在访问getProduct()。getName()属性时,我不会得到空指针。
refresh使用javax.persistence.EntityManager.refresh()根据buyProduct()方法中设置的id加载导航属性。
public class ProductServiceTest {
@InjectMocks
IProductService productService = new ProductService();
@Mock
IWriteANoteService writeANoteService;
@Mock
IAccountProductRepository accountProductRepository;
@Test
public void buyProductTest() {
productService.buyProduct(1l, 1l);
}
}
@Service
public class ProductService implements IProductService {
@Autowired
IWriteANoteService writeANoteService;
@Autowired
IAccountProductRepository accountProductRepository:
public void buyProduct(Long productId, Long accountId) {
AccountProductPojo accountProduct = new AccountProductPojo();
accountProduct.setProductId(productId);
accountProduct.setAccountId(accountId);
accountProductRepository.persist(accountProduct);
// load navigation properties
accountProductRepository.refresh(accountProduct);
writeANoteService.writeAccountNote(accountId, "Bought product " + accountProduct.getProduct().getName());
}
}
@Entity
@Table(name = "account_product")
public class AccountProductPojo {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "account_id")
private Long accountId;
@Column(name = "product_id")
private Integer productId;
@ManyToOne
@JoinColumn(name = "product_id", insertable = false, updatable = false)
private ProductPojo product;
@OneToOne(fetch = FetchType.LAZY, targetEntity = AccountPojo.class)
@JoinColumn(name = "account_id", insertable = false, updatable = false)
private AccountPojo account;
// getters and setters
}
答案 0 :(得分:2)
这似乎是mocking a void method的一个相当经典的案例。
您可以尝试这样的事情:
Mockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
AccountProductPojo accountProduct = (AccountProductPojo) args[0];
accountProduct.setProduct(new ProductPojo(PRODUCT_ID_CONSTANT, PRODUCT_NAME_CONSTANT));
return null;
}}).when(accountProductRepository).refresh(Mockito.any());
这里的关键是当在模拟上调用refresh()
时,你在POJO上调用setProduct()
,它作为refresh()
调用的参数传递,以避免后来的null指针异常。