如何使用Powermock在测试方法中设置类的私有成员变量

时间:2018-10-22 16:57:13

标签: junit mockito powermock powermockito

我正在为以下构造函数编写一个junit测试。我试图使用Membermodifier设置mapRecords变量的值,但仍然将零作为列表的大小。作为junit的新手,我没有确切的想法去做。如果有人可以帮助,将不胜感激。

公共类转换{

    private MapMetadataDAO mapMetadataDAO;
    private Map<String,String> srcTargetMap;
    private List<MapMetadata> mapRecords;

    public Transform(String transformationId) throws GenericFlowException {
        try {
            mapMetadataDAO=new MapMetadataDAO();
        } catch (DAOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mapRecords = mapMetadataDAO.findMapMetadataByTransformationID(transformationId);
        System.out.println(mapRecords.size()); 
        if(mapRecords.isEmpty()){
            throw new GenericFlowException("Map meta data is not defined for the transformationId "+transformationId);
        }
        map();
    }
}

测试类: 如果我不使用new创建对象,则无法调用构造函数

@RunWith(PowerMockRunner.class)
@PrepareForTest({Transform.class, MapMetadataDAO.class})
public class TransformTest {


    @Test
    public void constructorTest() throws Exception
    {
        PowerMockito.suppress(PowerMockito.constructor(MapMetadataDAO.class));

        MapMetadataDAO dao = PowerMockito.mock(MapMetadataDAO.class);
        MapMetadata mapMetaData = PowerMockito.mock(MapMetadata.class);
        PowerMockito.whenNew(MapMetadataDAO.class).withNoArguments().thenReturn(dao);
        List<MapMetadata> list = new ArrayList<>();
        list.add(mapMetaData);
        Transform trans = PowerMockito.mock(Transform.class, Mockito.CALLS_REAL_METHODS);
        MemberModifier.field(Transform.class, "mapRecords").set(trans, list);
        PowerMockito.when(dao.findMapMetadataByTransformationID("transformationID")).thenReturn(list);
        Transform transform = new Transform("transformationId");

        PowerMockito.whenNew(Transform.class).withAnyArguments().thenReturn(trans);

    }
}

2 个答案:

答案 0 :(得分:0)

为便于测试,请按如下所示重写您的类:

public class Transform {

    private MapMetadataDAO mapMetadataDAO;
    private Map<String,String> srcTargetMap;
    private List<MapMetadata> mapRecords;

    public Transform(MapMetadataDAO mapMedatadaDAO, String transformationId) throws GenericFlowException {
        mapRecords = mapMetadataDAO.findMapMetadataByTransformationID(transformationId);
        System.out.println(mapRecords.size()); 
        if(mapRecords.isEmpty()){
            throw new GenericFlowException("Map meta data is not defined for the transformationId "+transformationId);
        }
        map();
    }
}

然后进行测试:

                @RunWith(PowerMockRunner.class)
                @PrepareForTest({MapMetadataDAO.class})
                public class TransformTest {

                    @Test
                    public void constructorTest() throws Exception
                    {
        MapMetadata mapMetaData = new MapMetadata();
                        List<MapMetadata> list = new ArrayList<>();
                        list.add(mapMetaData);        
                        MapMetadataDAO dao = PowerMockito.mock(MapMetadataDAO.class);
    String transformationId = "transformationId";         
PowerMockito.when(dao.findMapMetadataByTransformationID(transformationId)).thenReturn(list);
                        Transform transform = new Transform(dao, transformationId);
                    }
                }

答案 1 :(得分:0)

通过对您的班级进行一些更改,我使其正常运行

struct LocationItem: Codable {
    var itemId: Int?
    var locationId: Int?
    var qty: Int?

    enum CodingKeys: String, CodingKey {
        case itemId = "ItemId"
        case locationId = "LocationId"
        case qty = "Qty"
    }
}

let decoder = JSONDecoder()

do {
    let responseStructure = try decoder.decode([[String:[[String:Any]]]], from: data)
} catch {
    // failed
}

let locationItems = responseStructure[0]["LocationsItems"]

让我知道这是否是您需要的