2016-01-22 107 views
2

這是我的代碼的一個非常簡化的版本,它說明了具體的問題。模擬加載導航屬性

有沒有什麼辦法可以控制從測試中調用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 
} 
+1

Mockito.when(yourMethod).thenReturn(something)。 https://mockito.googlecode.com/hg-history/1.7/javadoc/org/mockito/Mockito.html – Damiano

+0

除此之外,它看起來像buyProduct()中的一個bug,您可以在其中調用'setProductId(accountId)'。 productId參數未使用。 –

+0

哦,是的,這是一個複製粘貼錯誤,現在編輯。 – heuts

回答

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()叫上模擬你這是作爲一個參數,以避免傳遞給refresh()調用POJO調用setProduct()後面的空指針異常。

+0

這太好了,謝謝! – heuts