Java junit-如何进行真正的测试而不是模拟(改变结果)

Java junit-如何进行真正的测试而不是模拟(改变结果),java,unit-testing,junit,Java,Unit Testing,Junit,我已经编写了以下测试用例,但是我有点困惑这是否是一个好的测试。因为从我可以看出,当我用userDataMock进行模拟时,我正在改变真实的结果。所以我真的已经把最终结果改成了“预期”。因此,当我进行真正的测试时,唯一的结果是“预期的”,因为我已经用Mockito.when(userDataMock.doStandardLogin(loginInfoMock)).thenReturn(预期的) 我以前见过开发人员这样做,但我想要一个真正的测试。我做错了什么或没有想到什么 public class

我已经编写了以下测试用例,但是我有点困惑这是否是一个好的测试。因为从我可以看出,当我用userDataMock进行模拟时,我正在改变真实的结果。所以我真的已经把最终结果改成了“预期”。因此,当我进行真正的测试时,唯一的结果是“预期的”,因为我已经用
Mockito.when(userDataMock.doStandardLogin(loginInfoMock)).thenReturn(预期的)
我以前见过开发人员这样做,但我想要一个真正的测试。我做错了什么或没有想到什么

public class DoStandardLoginUsecaseTest {

  private DoStandardLoginUsecase target;
  private MyApplication contextMock;

  @Before
  public void beforeEach() {
      contextMock = Mockito.mock(MyApplication.class);
      // Note that you need to mock the getPresenterComponent
      // but I don't know what it returns.
      target = new DoStandardLoginUsecase(contextMock);
  }

  @Test
  public void buildUseCaseObservable() {
       UserDataRepository userDataMock = Mockito.mock(UserDataRepository.class);
       StandardLoginInfo loginInfoMock = Mockito.mock(StandardLoginInfo.class);
       target.mUserDataRepo = userDataMock;
       target.setLoginInfo(loginInfoMock);

       Observable<Login> expected = // create your expected test data however you like...
       Mockito.when(userDataMock.doStandardLogin(loginInfoMock)).thenReturn(expected);
       Observable<Login> actual = target.buildUseCaseObservable();

       Assert.areSame(actual, expected);
  }
公共类DoStandardLoginUsecaseTest{
私人剂量标准剂量目标;
私有MyApplication contextMock;
@以前
每个()之前的公共无效{
contextMock=Mockito.mock(MyApplication.class);
//请注意,您需要模拟getPresenterComponent
//但我不知道它会有什么回报。
目标=新剂量标准LoginUsecase(contextMock);
}
@试验
公共无效buildUseCaseObservable(){
UserDataRepository userDataMock=Mockito.mock(UserDataRepository.class);
StandardLoginInfo loginInfoMock=Mockito.mock(StandardLoginInfo.class);
target.mUserDataRepo=userDataMock;
target.setLoginInfo(loginInfoMock);
Observable expected=//以您喜欢的方式创建您的预期测试数据。。。
Mockito.when(userDataMock.doStandardLogin(loginInfoMock)).thenReturn(预期);
可观察的实际值=target.buildUseCaseObservable();
Assert.AreName(实际、预期);
}
}

更新:以下是我针对测试的实际类:

DoStandardLoginUsecase.java:

public class DoStandardLoginUsecase extends BaseUseCase {

@Inject
UserDataRepository mUserDataRepo;

private StandardLoginInfo loginInfo;

@Inject
public DoStandardLoginUsecase(UserDataRepository userDataRepository) {
mUserDataRepo = userDataRepository;
}

@Override
public Observable<Login> buildUseCaseObservable() {
    return mUserDataRepo.doStandardLogin(loginInfo);
}

public void setLoginInfo(StandardLoginInfo loginInfo) {
    this.loginInfo = loginInfo;
}
public类DoStandardLoginUsecase扩展了BaseUseCase{
@注入
UserDataRepository mUserDataRepo;
私人标准物流信息物流信息;
@注入
公共DosStandardLoginUseCase(UserDataRepository UserDataRepository){
mUserDataRepo=userDataRepository;
}
@凌驾
公共可观测buildUseCaseObservable(){
返回mUserDataRepo.doStandardLogin(loginInfo);
}
公共无效设置登录信息(标准登录信息登录信息){
this.loginInfo=loginInfo;
}

}

这是一个非常健康的想法,这是真的-当你嘲笑一切时,你最终会测试你的测试。不幸的是,今天嘲弄是一种非常普遍的做法,而且大多被滥用。您可以编写不同类型的测试,而不是模拟:

  • 单元测试将单独检查类。为了在不模仿的情况下实现这一点,您需要遵循良好的旧OOP,尤其是丰富的模型
  • 组件(也称为集成)测试——这些测试可以初始化应用程序的一部分,并检查一组类。例如,您可以使用内存中的DB初始化spring上下文
  • 系统测试针对完全部署的应用程序运行。如果它是一个UI,那么这些可能是Selenium测试。如果这是一个RESTAPI,那么可以重新进行测试

这被称为一个。但有时你还是想嘲笑。这通常发生在系统的边界上。例如,您从外部站点获取一些数据并解析结果。要检查解析,您实际上不需要连接到外部站点——您可以模拟获取数据的部分。这允许您编写非常快速和简单的测试。

您正在测试的代码/行为是什么?如果你不嘲笑这一点,你就很好。如果你甚至不执行测试中的代码,你就搞砸了。模拟的目的是控制输入,这是完全正确的。如果没有它,您无法测试某些条件。我正在尝试测试一个登录的用户,并测试我是否返回令牌。因此,在一个名为DoStandardLoginUsecase的类中,我调用UserDataRepository来实际执行一个改装调用。所以我更愿意在这里做一个真正的测试,得到一个真正的结果。你介意分享一下正在测试的方法吗?没有它很难判断考试的质量。我更新了我的问题。buildUseCaseObservable实际上将返回一个我可以订阅的Observable来触发登录rest调用。您可以进行集成测试或单元测试。在单元测试中,您使用模拟,只测试
DoStandardLoginUsecase
code。如果您需要从
mUserDataRepo
获取实际令牌,那么它将是集成测试。