具有许多依赖关系的模拟嵌套服务类



我有一堆服务类,它们看起来都很像或类似。

@Service
public class ServiceA {
private RepositoryA repA;
private RepositoryB repB;
private DependencyC depC;
private DependencyD depD;
private ServiceB serviceB;
@Autowired
public ServiceA(RepositoryA repA, RepositoryB repB, DependencyC depC, DependencyD depD, ServiceB serviceB) {
this.repA = repA;
....
}
}

现在,我想在不启动Spring的情况下在测试类中使用这些服务。如果我在应用程序上下文中使用bean,测试会花费太长时间。我想模拟服务类,但由于嵌套结构太深,我不知道如何模拟。简单的方法是模拟ServiceA使用的所有存储库、依赖项和服务,并将它们自己注入测试类中,但这似乎不对,因为我必须对ServiceB做同样的事情。

您可以使用mockito进行此操作,然后您的代码将类似于此

@RunWith(MockitoJUnitRunner.Silent.class)
public class ServiceATest {
@Mock
RepositoryA repA;
@Mock
RepositoryB repB;
@Mock
DependencyC depC;
@Mock
DependencyD depD;
@Mock
ServiceB serviceB;
@InjectMocks
ServiceA serviceA;
}

然后,当您需要在测试中使用mock时,您可以模拟模拟类的方法,例如:

@Test
public void someTest() {
...
when(repA.repMethod()).thenReturn(new SomeObject());

SomeObject mockedObject = serviceA.serviceMethod(); // if serviceMethod call repMethod, you will get the object which you passed in youк mock method call
...
}

两种选择:

  1. 模拟ServiceB
  2. 按照您所描述的操作,因为您无论如何都要这样做,以便为ServiceB编写测试,以便重用该工作
  3. 构建一个充满mock的替代Spring上下文,并将其用于测试

我通常选择2。它是不纯净的,因为ServiceA的正确性取决于ServiceB的正确性,但编写、管理和理解的测试代码较少。

public class ServiceATest {
private RepositoryA repA;
private RepositoryB repB;
private DependencyC depC;
private DependencyD depD;
private ServiceB serviceB;
@Before
public void init() { 
this.repB = mock(RepositoryA.class);
.....
// mock all repositories you need.
this.serveceB = new ServiceB(repoB,...);
//then use contructor method to instantiate serviceB. Also do same with 
//serviceB 
this.serviceA = new ServiceA(repA,  repB,depC, depD, serviceB)
}

//Write the tests like that
@Test
public void saveanything_shouldBeCorect() {
when(repoA.save()any()).thenReturn(mySavedMock);
MyVariable resp = serviceA.save(myMock);
// them assert your resp.
}

}

重要的是使用mockito方法";当(rep.anython(any((((仅在已移动到init方法的存储库中时。

最新更新