Java 使用构造函数注入模拟spring类
我有以下课程:Java 使用构造函数注入模拟spring类,java,spring,unit-testing,mockito,Java,Spring,Unit Testing,Mockito,我有以下课程: @Service public class SomeClass extends BaseClass { private final SomeService someService; public SomeClass(SomeService someService) { this.someService = someService; } public List<String> methodToTest(SomeDataClass data)
@Service
public class SomeClass extends BaseClass {
private final SomeService someService;
public SomeClass(SomeService someService) {
this.someService = someService;
}
public List<String> methodToTest(SomeDataClass data) {
if (!checkData(data)) { // checkData is defined in BaseClass and does lots of unimportant stuff
throw BadDataException();
}
return someService.getData();
}
}
但是,我在创建testcase#2时遇到了问题。我可以使用SomeClass SomeClass=new SomeClass(mockSomeService)
手动创建SomeClass,但是我需要为扩展checkData()请求创建模拟数据,我实际上不想在这个测试用例中测试它,因为它已经被一个不同的测试所覆盖,并且需要大量不必要的模拟,或者我可以模仿testcase#1中的某个类,但不管我怎么做,某个服务总是空的
我尝试了@InjectMocks、@Mock之类的变体,但没有找到可行的解决方案
我尝试过的事情:
@Mock
private SomeService someService;
@Before
public void setUp() {
someService = mock(SomeService.class);
when(someService.getData()).thenReturn(Collections.singletonList("Mock"));
}
@Test
public void methodToTest_someServiceCalled1() {
SomeClass mock = mock(SomeClass.class);
when(mock.methodToTest(any()).thenCallRealMethod();
when(mock.checkData(any()).thenReturn(true);
List<String> result = mock.methodToTest(new SomeData()); // NullPointerException at someService.getData() call
verify(someService).getData();
assertEquals("Mock", result.get(0));
}
@Test
public void methodToTest_someServiceCalled2() {
SomeClass someClass = new SomeClass(someService);
List<String> result = someClass.methodToTest(new SomeData()); // Fails at checkData() call
verify(someService).getData();
assertEquals("Mock", result.get(0));
}
@Mock
私人服务;
@以前
公共作废设置(){
someService=mock(someService.class);
when(someService.getData()).thenReturn(Collections.singletonList(“Mock”));
}
@试验
public void methodToTest_someServiceCalled1(){
SomeClass mock=mock(SomeClass.class);
when(mock.methodToTest(any()).thenCallRealMethod();
when(mock.checkData(any())。然后返回(true);
List result=mock.methodToTest(new SomeData());//调用someService.getData()时出现NullPointerException
验证(someService).getData();
assertEquals(“Mock”,result.get(0));
}
@试验
public void methodToTest_someServiceCalled2(){
SomeClass SomeClass=新的SomeClass(someService);
List result=someClass.methodToTest(new SomeData());//在checkData()调用时失败
验证(someService).getData();
assertEquals(“Mock”,result.get(0));
}
如何在模拟对父类checkData()的调用的同时调用someService的mock?是否可以不重构SomeClass?如果创建类的mock,则其中不会有任何依赖项。而是在真实实例上使用spy 下面是一个工作示例
@Mock
private SomeService someService;
@InjectMocks
private SomeClass classUnderTest;
@Before
public void setUp() {
Mockito.when(someService.getData()).thenReturn(Collections.singletonList("Mock"));
}
@Test
public void methodToTest_someServiceCalled1() {
SomeClass spy = Mockito.spy(classUnderTest);
Mockito.when(spy.checkData(Mockito.any())).thenReturn(true);
List<String> result = spy.methodToTest(new SomeData());
Mockito.verify(someService).getData();
assertEquals("Mock", result.get(0));
}
@Mock
私人服务;
@注射模拟
测试中的私有类;
@以前
公共作废设置(){
Mockito.when(someService.getData()).thenReturn(Collections.singletonList(“Mock”);
}
@试验
public void methodToTest_someServiceCalled1(){
SomeClass spy=Mockito.spy(classUnderTest);
Mockito.when(spy.checkData(Mockito.any())。然后返回(true);
List result=spy.methodToTest(new SomeData());
验证(someService.getData();
assertEquals(“Mock”,result.get(0));
}
我不确定你是否是第二次测试,好吧,我会调用原始的
checkData
方法。正如你提到的,这是你想要避免的,解决方案应该与第一次测试类似。你可能想使用spy
。你能添加你尝试编写的测试吗?@第二次我添加了我已经添加的测试Ed您想测试SomeService
不要模拟它,而是模拟依赖项。@MDeinum否,他们不想测试SomeService
-他们想测试getData()
被调用。正确的方法是对SomeClass
进行间谍,对SomeService
进行模拟。这实际上非常有效。谢谢。我知道不调用checkData是“错误的”,因为它是方法契约的一部分,但由于它被许多类调用,所以我决定对它进行显式测试,而不是在所有派生类中使用模拟数据。
@Mock
private SomeService someService;
@InjectMocks
private SomeClass classUnderTest;
@Before
public void setUp() {
Mockito.when(someService.getData()).thenReturn(Collections.singletonList("Mock"));
}
@Test
public void methodToTest_someServiceCalled1() {
SomeClass spy = Mockito.spy(classUnderTest);
Mockito.when(spy.checkData(Mockito.any())).thenReturn(true);
List<String> result = spy.methodToTest(new SomeData());
Mockito.verify(someService).getData();
assertEquals("Mock", result.get(0));
}