Mockito使用内部方法模拟java函数

时间:2017-10-04 22:12:35

标签: java function junit mockito

我有一个类似的课程:

@Component
    public class AddressConverter {

        public Function<Address, AddressDTO> convertToDTO = new Function<Address, AddressDTO>() {
            public AddressDTO apply(Address address) {
                AddressDTO dto = new AddressDTO();
                dto.setAddress1(address.getAddress1());
                dto.setAddress2(address.getAddress2());
                dto.setCity(address.getCity());
                dto.setState(address.getState());
                dto.setZip(address.getZip());
                dto.setZip4(address.getZip4());
                return dto;
            }
        };
}

我有另一个使用它的类:

     @Component
            public class ProfileConverter {

                @Autowired
                private AddressConverter addressConverter;

                public Function<Profile, ProfileDTO> convertToDTO = new Function<Profile, ProfileDTO>() {
                    public ProfileDTO apply(Profile profile) {
                        ProfileDTO dto = new ProfileDTO();  
        dto.setEmployeeAddress(addressConverter.convertToDTO.apply(profile.getEmployeeAddress()));
return dto;
                    }
                };
    }

我正在尝试模拟addressConverter类,如:

EDIT: HERE IS THE TEST CLASS

public class ProfileConverterTest {

    ProfileConverter converter;
    AddressConverter addressConverter;
    Profile profile;
    ProfileDTO dto;
    Address address;
    AddressDTO addressDTO;

    @Before
    public void setUp() {
        converter = new ProfileConverter();
        addressConverter = Mockito.mock(AddressConverter.class);
        profile = new Profile();
        profile.setProfileId(123L);
        dto = new ProfileDTO();
        Mockito.when(addressConverter.convertFromDTO.apply(addressDTO)).thenReturn(address);
        Mockito.when(addressConverter.convertToDTO.apply(address)).thenReturn(addressDTO);
        ReflectionTestUtils.setField(converter, "addressConverter", addressConverter);
        address = new Address("1","2","3","4","5","6");
        address.setAddressId(123L);
        addressDTO = new AddressDTO("hash","1","2","3","4","5","6");
    }

    @Test
    public void applyReturnsProfileDTO() throws Exception {
        ProfileDTO result = converter.convertToDTO.apply(profile);
assertEquals(result.getEmployeeAddress().getAddress1(), profile.getEmployeeAddress().getAddress1());
}
}

我在第一个Mockito.when行的测试中不断收到NullPointerException。我认为它是由mock addressConverter类调用一个调用内部方法的函数引起的。该函数可能为null?

2 个答案:

答案 0 :(得分:1)

你期待Mockito调用你的类构造函数来初始化字段convertToDTO:事实并非如此,这里的简单测试就证明了这一点:

  @Test
  public void test_that_yeepee_works() {
    final Yeepee y = Mockito.mock(Yeepee.class);    
    Assertions.assertNotNull(y.myObject); // fails.
  }

  public static class Yeepee {
    public Object myObject = new Object();
  }

您可以尝试使用Mockito.spy

或者你需要明确地这样做:

converter = new ProfileConverter();
addressConverter = Mockito.mock(AddressConverter.class);
addressConverter.convertToDTO = (Function<Address, AddressDTO>) Mockito.mock(Function.class);

如果您使用的是吸气剂,Mockito可能会使用智能模拟器为您完成。

答案 1 :(得分:0)

我认为,NPE是因为你没有为AddressConverter类创建一个模拟器。你应该写下面的东西:

AddressConverter addressConverter = Mockito.mock(AddressConverter.class);
Mockito.when(addressConverter.apply(any(Address.class))).thenReturn(addressDTO);

注意:任何(Address.class)都匹配Address类的任何对象。如果您想在调用(模拟)应用方法时测试使用地址对象的天气,请继续在hashcode()课程中添加equals()Address实施。