繁体   English   中英

如何在测试时将模拟对象注入类中?

[英]How to inject a mock object to a class when testing?

我的用户类如下,

public class UserResource {
  @Inject UserService userService;

  public boolean createUser(User user) {
    DbResponse res = userService.addUser(user);
    if(res.isSuccess){
      return true;
    }else{
      return false;
    }
  }
}

我的测试类看起来如下,

public class UserResourceTest {

  UserResource userResource;

  @BeforeMethod
  void beforeMethod() {
    userResource = new UserResource();
  }

  @Test
  public void test() {
    User user= mock(User.class);
    boolean res= userResource.createUser(user);
    assert(res);
  }
}

如您所见,应将UserService对象注入UserResource类。 如何在我的测试中将模拟UserService对象注入到userResource对象中?

供参考:

  • 这是Jersey JAX-RS项目的一部分。
  • 我正在使用Java CDI,mockito和testNG(作为测试库)。

考虑通过构造函数注入使用显式依赖主体,因为它非常清楚地说明了类为了执行其特定功能所需的内容。

public class UserResource {
  private UserService userService;

  @Inject
  public UserResource(UserService userService) {
    this.userService = userService;
  }

  public boolean createUser(User user) {
    DbResponse res = userService.addUser(user);
    if(res.isSuccess){
      return true;
    }else{
      return false;
    }
  }
}

并模拟UserService并将其分配给受测试的主题。 配置测试的所需/模拟行为。

public class UserResourceTest {

  @Test
  public void test() {
    //Arrange
    boolean expected = true; 
    DbResponse mockResponse = mock(DbResponse.class);
    when(mockResponse.isSuccess).thenReturn(expected);

    User user = mock(User.class);
    UserService mockService = mock(UserService.class);
    when(mockService.addUser(user)).thenReturn(mockResponse);

    UserResource userResource = new UserResource(mockService);        

    //Act
    boolean actual = userResource.createUser(user);

    //Assert
    assert(expected == actual);
  }
}

虽然我完全支持@Nkosi的答案,但我想补充一下这个完整性:

使用Mockitos JUnitRule来修改JUnitRule ,如下所述: httpJUnitRule

public class UserResourceTest {
    @Rule 
    public MockitoRule mockitoRule = MockitoJUnit.rule(); 
    @Mock
    private  DbResponse mockResponse;
    @Mock
    private UserService mockService;    

    @Test
    public void test() {
        //Arrange
        boolean expected = true; 
        when(mockResponse.isSuccess).thenReturn(expected);
        when(mockService.addUser(user)).thenReturn(mockResponse);
        // ...

此外,您还可以使用Mockitos @InjectMocks注释,如下所示:

public class UserResourceTest {
    @Rule 
    public MockitoRule mockitoRule = MockitoJUnit.rule(); 
    @Mock
    private  DbResponse mockResponse;
    @Mock
    private UserService mockService;
    @InjectMocks
    private UserResource userResource; // do not instantiate in test method
     // ...

但我个人会劝阻它。

是的,它更方便,因为它通过反射确定您使用的依赖注入方法。 但是如果你没有一个“接缝”来注入某个依赖项(既不是Costructor参数 ,也不是非最终属性,也不是匹配类型的setter ),你就不会遇到我个人觉得有问题的编译错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM