简体   繁体   English

使用JUnit和Mockito测试类时获取异常

[英]Getting exception while testing a class using JUnit and Mockito

I am trying to unit test a service layer class that is written on top of DAO layer but getting following exception. 我正在尝试对在DAO层之上编写的服务层类进行单元测试,但遇到以下异常。

Please guide. 请指导。

Exception 例外

Running com.ministore.service.MasterDataServiceTest
actStates = null
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.941 sec <<< FAILURE!
testGetAllStates(com.ministore.service.MasterDataServiceTest)  Time elapsed: 0.8 sec  <<< FAILURE!
junit.framework.AssertionFailedError
    at junit.framework.Assert.fail(Assert.java:48)
    at junit.framework.Assert.assertTrue(Assert.java:20)
    at junit.framework.Assert.assertNotNull(Assert.java:218)
    at junit.framework.Assert.assertNotNull(Assert.java:211)
    at com.ministore.service.MasterDataServiceTest.testGetAllStates(MasterDataServiceTest.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)


Results :

Failed tests:   testGetAllStates(com.ministore.service.MasterDataServiceTest)

MasterDataServiceTest.java MasterDataServiceTest.java

public class MasterDataServiceTest {

    @Mock
    DataSource dataSource;
    @Mock
    MasterDao dao;
    @Mock
    Connection cn;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testGetAllStates() throws SQLException {
        MasterDataService dataService = new MasterDataServiceImpl(dataSource);

        when(dao.getAllStates()).thenReturn(new ArrayList<State>());
        when(dataSource.getConnection()).thenReturn(cn);

        List<State> actStates = dataService.getAllStates();
        System.out.println("actStates = " + actStates);
        assertNotNull(actStates);
    }

}

MasterDataServiceImpl.java MasterDataServiceImpl.java

public class MasterDataServiceImpl implements MasterDataService {

    private final DataSource dataSource;

    public MasterDataServiceImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public List<State> getAllStates() throws SQLException {
        return new MasterDaoImpl(dataSource).getAllStates();
    }

}

MasterDaoImpl.java MasterDaoImpl.java

public class MasterDaoImpl extends BaseDao implements MasterDao { 公共类MasterDaoImpl扩展BaseDao实现MasterDao {

private static final Logger LOG = Logger.getLogger(MasterDaoImpl.class);

public MasterDaoImpl(DataSource dataSource) {
    super(dataSource);
}

@Override
public List<State> getAllStates() throws SQLException {
    String sql = "select * from states a order by a.name";
    return QueryExecutor.executeStatesQuery(dataSource.getConnection(), sql);
}

} }

BaseDao.java BaseDao.java

public abstract class BaseDao {

    protected DataSource dataSource;

    public BaseDao(DataSource dataSource) {
        this.dataSource = dataSource;
    }

}
  @Override
    public List<State> getAllStates() throws SQLException {
        return new MasterDaoImpl(dataSource).getAllStates();
    }

The service is creating a new dao each time the method is called. 每次调用该方法时,服务都会创建一个新的域。 The mock you are creating in the test is not being used by the service. 服务未使用您在测试中创建的模拟。

It's normal. 这是正常的。 because the mocked dao reference is never given to your service. 因为模拟的dao参考永远不会提供给您的服务。 In your MasterDataServiceImpl.getAllStates() you make a new instance of your dao. 在您的MasterDataServiceImpl.getAllStates() ,创建一个dao的新实例。 Solution : you can implement a setter, so you can inject your mocked dao. 解决方案:您可以实现一个setter,因此可以注入模拟的dao。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM