I am trying to test the "provisionProduct()" method in some legacy code. As you can see, it eventually makes a call on productDAO, which I want to mock out.

@Service( "productService" )
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class ProductServiceImpl implements IProductService
{
    private ProductDAO productDAO;

    @Autowired
    public ProductServiceImpl(ProductDAO dao)
    {
        productDAO = dao;
    }

    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public ProductProvisionResponseDTO provisionProduct(Long productId, String serverName) throws PortalException
    {
        [...]
        try
        {
            Product product = productDAO.findProductById(productId);
        [...]
    }
}

Here is my test:

public class ProductServiceTest
{
    @Mocked
    private ProductDAO m_mockProductDAO;

    private IProductService m_productService;

    @Test
    public void provisionProduct_noProfileAssociatedToProduct_throwsPortalException() throws PortalException, DAOException
    {
        m_productService = new ProductServiceImpl( m_mockProductDAO );

        new NonStrictExpectations()
        {
            {
                m_mockProductDAO.findByProductId( anyLong );
                result = new Product();
            }
        };

        m_productService.provisionProduct( 123456789L, "don't care" );
    }
}

When I run the test, the call on productDAO always returns null.

FWIW I can step into the findProductById() method, which takes me into JMockit's RecordAndReplayExecution class. When JMockit gets to handleInvocation(), the nonStrictExpectation is null, and later produceResult() gives null.

I believe this is a straightforward test case, but I am uncertain about whether Spring is somehow causing undesired effects, which is why I left the various annotations in my code snippets. Admittedly I'm not very familiar with how Spring works. I am directly instantiating the ProductServiceImpl, though, so I don't believe Spring is coming into play there.

Any ideas? Am I missing something totally obvious?

JMockit v1.8, JUnit v4.8.2

有帮助吗?

解决方案 2

  • The legacy code had two identical methods that were named slightly differently. I came to realize this when Rogerio noted that my recorded expectation was different from what I was testing.
  • My JMockit usage was otherwise correct.

其他提示

There is also a method in JMockit which could help solve your problem:

Deencapsulation's setField

This way you'll tell the JMockit that the null attribute in original class should be replaced by mocked object from test class. I already experienced similar error like you do and this helped me.

Similarly, there is also method getField, which helps you to get the value of the current private attribute of the class during the test.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top