如何在UnitTest类中将对象传递给我的测试类?

时间:2017-01-24 07:40:17

标签: java spring unit-testing mockito inject

我想测试一个具有" ObjectMapper"的类。作为实例变量:

public class EventTransformerImpl implements EventTransformer {


 @Inject
 private ObjectMapper objectMapper;

private String convertParametersToJson(NotificationConfig config) {
        String parametersAsJson = null;
        try {
            parametersAsJson = objectMapper.writeValueAsString(config.getOrdinaryParameters());
        } catch (IOException e) {
            logger.info("There was a problem in writing json:" + config.getParameters(), e);
            parametersAsJson = null;
        }
        return parametersAsJson;
    }
}

这个班级没有任何" setter"或"构造函数"用于初始化" objectMapper" (它使用" spring"初始化):

<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
    <property name="dateFormat">
        <bean class="java.text.SimpleDateFormat">
            <constructor-arg value="yyyy-MM-dd'T'HH:mm:ssZ"/>
        </bean>
    </property>
</bean>

当我想测试&#34; EventTransformerImpl&#34; class,objectMapper有null值,我怎样才能传递&#34; objectMapper&#34; to&#34; EventTransformerImpl&#34;在我的单元测试课程中。

4 个答案:

答案 0 :(得分:3)

这是一个典型的示例,其中模拟框架(例如Mockito)可以帮助您:

public class TestClass {
  @Mock
  private ObjectMapper objectMapper;

  @InjectMocks
  private EventTransformer eventTransformer;

  @BeforeMethod
  public void setUp() {
    eventTransformer = new EventTransformerImpl();
    MockitoAnnotations.initMocks(this);
  }  
}

此处,@Mock@InjectMocks是Mockito框架的一部分。魔术发生在MockitoAnnotations.initMocks(this),会扫描this,在这种情况下为TestClass,用于这些注释。 Mockito将objectMapper初始化为模拟,并将其注入eventTransformer。然后,您可以使用Mockito来决定objectMapper的行为方式。

您可以阅读有关Mockito here的更多信息。

此外,@BeforeMethod是一个TestNG方法,类似于JUnits @Before

然而,许多人更喜欢constructor injection提出的davidxxx。这将使哪个依赖项EventTransformerImpl更清楚,并强制使用正确的依赖项进行初始化。通过这样做,没有必要&#34;神奇地&#34; (我猜Mockito在引擎盖下使用反射)注入依赖项,只需通过调用构造函数初始化要测试的类。

你的课可能看起来像这样(这里使用的是Spring {#1}}注释):

@Autowired

这样不容易出错,因为对于public class EventTransformerImpl implements EventTransformer { private ObjectMapper objectMapper; @Autowired public EventTransformerImpl(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } private String convertParametersToJson(NotificationConfig config) { String parametersAsJson = null; try { parametersAsJson = objectMapper.writeValueAsString(config.getOrdinaryParameters()); } catch (IOException e) { logger.info("There was a problem in writing json:" + config.getParameters(), e); parametersAsJson = null; } return parametersAsJson; } } ,如果失败,Mockito会默默地忽略注入,而调用构造函数则会让测试类完全控制测试的初始化。

答案 1 :(得分:1)

1)一个类应该是自然可测试的:为什么不在EventTransformerImpl中添加构造函数来注入映射器?

您可以在弹簧配置中执行类似的操作:

  <bean id="EventTransformer" class="EventTransformerImpl">
      <constructor-arg ref="objectMapper"/>
   </bean>

在测试中,您可以在构造函数中使用EventTransformerImpl模拟的依赖项实例化ObjectMapper

2)另一种解决方案是使用反射在测试方法中将测试中的场注入。

你可以使用ReflectionTestUtils类的public static final void injectValue(String fieldName, Object fieldValue, Object targetObject) { try { Field f = targetObject.getClass().getDeclaredField(fieldName); f.setAccessible(true); f.set(targetObject, fieldValue); } catch (Exception e) { // handle the exception } } 类来设置依赖关系,或者如果你没有使用Spring,你可以编写一个简单的实用工具方法来完成这项工作:

http://192.168.0.10/set_camprop.cgi?com=setlist

答案 2 :(得分:1)

为了在JUnit测试和其他依赖的对象中注入Spring依赖项,我使用

SELECT * FROM OPENQUERY ([DVT-FUSION],
'EXEC CRM_DVT.dbo.SP_RPT_Billing_Summary ''R1'', ''R2'', ''0'', ''0''  ')

您也可以提供代码bean初始化

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:testBeans.xml" })
public class TestRunner {

    @Test
    public void test1() {

https://www.mkyong.com/unittest/junit-spring-integration-example/

了解详情

答案 3 :(得分:1)

这三个答案都很好;所以我不需要重复那些细节,但我认为值得在“完整”图片上“对齐”。

如图所示 Spring 内置了为单元测试进行注入的方法;你可以继续前进并使用它。但是,当然,这意味着您将业务逻辑代码更“耦合”到Spring框架。

因此,如果你考虑在非Spring情况下重新使用你的代码,那么你会发现不仅你的生产代码,而且你的单元测试需要重大的返工才能在没有Spring的情况下使用。

因此,在其他两个答案中有一些优点,建议更改您的生产代码,以便您至少可以完全测试您的生产代码,而无需在此处向Spring添加依赖项。