【问题标题】:Inject private field to tested method将私有字段注入测试方法
【发布时间】:2018-01-12 13:09:29
【问题描述】:

简单的问题,我有一个类,其中有一个包含 Items 的 List 字段,我有一个在该 List 上运行的方法,检查是否有一个 Item 具有在参数中给出的名称并返回 true 或 false。我想测试那个方法,在测试类中创建一个 ArrayList,模拟 JdbcItemDao 类,然后调用一个方法。测试中的方法无法到达数组,如何解决?代码:

     public class JdbcItemDao {
     private List<Item> tempStockList;

    public JdbcItemDao() {

    this.tempStockList = getAllStockItems();

   //getting items from my sql, returning them as ArrayList

}

  public boolean checkStockItems(String itemName) {
    for (Item item : tempStockList) {
        if (item.getItemName().equalsIgnoreCase(itemName)) {
            return true;
        }
    }
    return false;
}}

测试类:

public class JdbcTest {


JdbcItemDao jdbcItemDao;
List<Item> tempStockList;

@Before
public void setup() {

    jdbcItemDao = mock(JdbcItemDao.class);
    tempStockList = new ArrayList<>();
    tempStockList.add(new Item(1, "LEDTv", new BigInteger("40"),
            new Integer("3"), new BigInteger("70")));

}


@Test
public void checkStockItemsName() throws Exception {

   assertTrue(jdbcItemDao.checkStockItems("LEDTv"));

}}

【问题讨论】:

  • 不确定是否需要模拟它。您不想调用 getAllStockItems 方法吗?
  • 永远不要模拟你正在测试的课程:)

标签: java unit-testing testing mockito


【解决方案1】:

如果你不能重构我猜你的左边是创建一个私有类,覆盖方法并使用该类进行测试:

public class JdbcTest {

   List<Item> tempStockList = new ArrayList<>();

   @Before
   public void setup() {

    tempStockList = new ArrayList<>();
    tempStockList.add(new Item(1, "LEDTv", new BigInteger("40"),
            new Integer("3"), new BigInteger("70")));

   }


   @Test
   public void checkStockItemsName() throws Exception {
     JdbcItemDao jdbcItemDao = new CustomJdbcItemDao();
     assertTrue(jdbcItemDao.checkStockItems("LEDTv"));

   }

   private class CustomJdbcItemDao extends JdbcItemDao{

      @Override
      public List<Item> getAllStockItems(){
        return tempStockList;
      }
   }

}

【讨论】:

    【解决方案2】:

    您使用了错误类型的测试替身。你需要一个 spy (它是一个真实实现的包装器)而不是一个 mock (它是一个覆盖模拟类的所有方法的子类):

    jdbcItemDao = spy(new JdbcItemDao());
    
    tempStockList = new ArrayList<>();
    tempStockList.add(new Item(1, "LEDTv", new BigInteger("40"),
            new Integer("3"), new BigInteger("70")));
    doReturn(tempStockList).when(jdbcItemDao).getAllStockItems();
    

    关闭,因为这仅在您移动时才有效

    this.tempStockList = getAllStockItems();
    

    在构造函数之外...

    【讨论】:

      【解决方案3】:

      有一个方法'getAllStockItems',它在JdbcItemDao.java 类中

      public List<Item> getAllStockItems() {
          return jdbcTemplate.query(SELECT_ALL_STOCK_ITEMS, itemRowMapper);
      }
      

      它从 MySQL 数据库中获取数据,所以我想在测试中使用假数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-01
        • 1970-01-01
        • 2020-08-03
        • 2017-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多