在Junit测试运行期间,带有@Qualifer的@Mockbean会抛出

时间:2018-10-04 11:57:30

标签: spring spring-boot junit repository spring-boot-test

我正在写下课的内容,

@Repository
public class IncidentRepository {

    @Autowired
    @Qualifier("mysqlJdbcTemplate")
    private JdbcTemplate mysqlJdbcTemplate;


    @Autowired
    @Qualifier("oracleJdbcTemplate")
    private JdbcTemplate oracleJdbcTemplate;

    private String tableName = "BSC_INCIDENT_STG_3";


    public String getTableName() {
        return tableName;
    }

    public List<Incident> listAll() {
        String cprSql = "SELECT 1 FROM DUAL";
        return oracleJdbcTemplate.query(cprSql, new IncidentMapper());

    }
}

我正在研究的Junit班就是这个

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = CommonConfig.class)
public class IncidentRepositoryTest {

    private final Logger log = LoggerFactory.getLogger(Application.class);

    @InjectMocks
    IncidentRepository incidentRepository;

    @Qualifier("mysqlJdbcTemplate")
    private JdbcTemplate mysqlJdbcTemplate;

    @Qualifier("oracleJdbcTemplate")
    private JdbcTemplate oracleJdbcTemplate;

    @MockBean
    private Incident incident;

@MockBean
    private IncidentMapper incidentMapper;

    private String deleteSqlQuery = "DELETE FROM ";

    String cprSql = "SELECT 1 FROM DUAL";

    List<Incident> incidentList = new ArrayList<Incident>();

    @Before
    public void setUp() throws Exception {
        //All Initializations goes here.
        MockitoAnnotations.initMocks(this);     
        mysqlJdbcTemplate = Mockito.mock(JdbcTemplate.class);
        oracleJdbcTemplate = Mockito.mock(JdbcTemplate.class);

        incident.setIncidentNumber("incidentNumber");
        incident.setApplicationId("J12342");
        incident.setCategory("O12987");
        incident.setOpenTime("ApplicationName");
        incident.setSeverityCode("OwningLob");
        incident.setAssignment("reportingCIOLOB");
        incident.setStatus("reportingCTOGroup");
        incident.setCloseTime("rto");
        incident.setStatus("status");
        incident.setElapsedTime("assetName");
        incident.setResolutionCode("environment");
        incident.setType("invNo");
        incident.setOpenGroup("osiStatus");
        incident.setResolvedGroup("measuredID");
        incident.setResolvedTime("policyID");
        incident.setUserPriority("policyName");
        incident.setJpAcctLob("lastBreakDate");
        incident.setJpAcctAppRto("lastClearedDate");
        incident.setJpImpact("osiStatus");
        incident.setJpImpactDurationMin("measuredID");
        incident.setJpExternalId("policyID");
        incident.setJpExternalSystem("policyName");
        incident.setJpConfigItem("lastBreakDate");
        incident.setJpMasterHost("lastClearedDate");
        incident.setJpSite("osiStatus");
        incident.setJpAppserviceName("measuredID");
        incident.setJpAppserviceId("policyID");
        incident.setJpVerumidentifier("policyName");

        incidentList.add(incident);

    }

    @Test
    public void testListAll() throws Exception {

when(oracleJdbcTemplate.query(cprSql,incidentMapper)).thenReturn(incidentList);
        incidentRepository.listAll();       
    }
}

现在的问题是,即使我嘲笑了mysqlJdbcTemplate对象,在IncidentRepository类中始终为null。

我不想@Autowired注释。我只想模拟对象。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

如果我没记错的话,无论哪种情况,Mockito都将自动尝试在带有@InjectMocks的任何字段中注入模拟:

  1. 使用MockitoJUnitRunner
  2. 运行测试
  3. 使用MockitoAnnotations.initMocks(this)
  4. 引导测试

您选择了第二种方法,但是未将JdbcTemplate注入到模拟中的原因是因为您没有使用JdbcTemplate字段来模拟那些@Mock字段。

因此,首先,如下更改您的JdbcTemplate字段:

@Mock(name = "mysqlJdbcTemplate")
private JdbcTemplate mysqlJdbcTemplate;

@Mock(name = "oracleJdbcTemplate")
private JdbcTemplate oracleJdbcTemplate;

使用this question中所述,使用Mockito和相同类型的模拟似乎存在问题。另外,您可以使用构造函数注入并自己对其进行模拟,例如:

@Before
public void setUp() {
    mysqlJdbcTemplate = Mockito.mock(JdbcTemplate.class);
    oracleJdbcTemplate = Mockito.mock(JdbcTemplate.class);
    repository = new IncidentRepository(mysqlJdbcTemplate, oracleJdbcTemplate);
}

此外,如果您不想使用自动装配,则无需使用SpringRunner引导测试,因此可以安全地删除以下注释:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = CommonConfig.class) 

此外,您可以使用以下注释替换它们,就像我之前提到的那样:

@RunWith(MockitoJUnitRunner.class)

但是,当您不使用SpringRunner运行时,@MockBean注释将不起作用,但是您可以将其替换为@Mock注释,例如:

@Mock
private IncidentMapper incidentMapper;

但是,您没有在任何地方使用IncidentMapper,并且由于您的测试未检查该Incident中的任何字段,因此您可以简化测试,直到得到:

@RunWith(MockitoJUnitRunner.class)
public class IncidentRepositoryTest {
    @InjectMocks
    private IncidentRepository incidentRepository;
    @Mock(name = "mysqlJdbcTemplate")
    private JdbcTemplate mysqlJdbcTemplate;
    @Mock(name = "oracleJdbcTemplate")
    private JdbcTemplate oracleJdbcTemplate;

    @Test
    public void testListAll() {
        List<Incident> list = Lists.newArrayList(new Incident());
        when(oracleJdbcTemplate.query(eq("SELECT 1 FROM DUAL"), any(IncidentMapper.class)).thenReturn(list);
        assertThat(repository.listAll()).isSameAs(list);
    }
}