英文:
Best practice to mock/stub object created by constructor in a method
问题
I understand your request. Here's the translated part:
考虑一个带有参数化构造函数的POJO类:
public class Pojo {
private String field1;
private String field2;
public Pojo(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
}
现在我有一个需要进行单元测试的类,其中一个方法通过构造函数创建Pojo对象:
public class AnInjectMock {
private ServiceClass serviceClass;
public void runTransaction(Param1 param1, Param2 param2 ...) {
Pojo pojo = new Pojo(param1.getField1(), param2.getField2());
serviceClass.createTransaction(pojo, /*other fields*/);
// ...
}
}
我认为这不是一个罕见的实现场景。但是就单元测试而言,我试图找出一种只使用Mockito来存根构造函数对象的方法。我知道在Mockito 3.5之后有支持模拟构造函数,但是根据文档和其他在线教程,我找不到任何关于存根带有参数化构造函数的对象的信息。我可以接受对构造函数使用any()
值。
英文:
(Currently I have junit and Mockito, PowerMock or EasyMock is not an option)
Considering a POJO class with parameterized constructor
public class Pojo{
private String field1;
private String field2;
public Pojo(String field1, String field2){
this.field1=field1, this.field2=field2;
}
}
Now I have a class requires unit test and one of the method create Pojo object by the constructor
public class AnInjectMock{
private ServiceClass serviceClass;
//....
public void runTransaction(Param1 param1, Param2 param2 ...){
Pojo pojo = new Pojo(param1.getFiel1(), param2.getField2();
serviceClass.createTransaction(pojo, /*other fields*/};
.....
}
}
I think this is not an uncommon implementation scenario. But as for unit test, I try to figure out a way to use Mockito only to stub the constructor object. I get it that after Mockito 3.5 there is support to mock constructor, however per the document and other online tutorial I couldn't find anything to stub the object with parameterized constructor. I am Ok with any()
value for the constructor.
答案1
得分: 1
Here is the translated code portion:
如果我理解正确,您需要模拟对象内的参数。我认为您可以使用`when()`轻松模拟这些参数。
@ExtendWith(MockitoExtension.class)
class AnInjectMockTest {
@InjectMocks
private AnInjectMock anInjectMock;
@Mock
private ServiceClass serviceClass;
@Mock
private Param1 param1;
@Mock
private Param2 param2;
@Test
public void myTest() {
when(param1.getField1()).thenReturn(any());
when(param2.getField2()).thenReturn(any());
anInjectMock.createTransaction(pojo, /*other fields*/};
}
}
顺便说一下,您为什么需要模拟它?也许更好的方法是从pojo创建一个对象,然后模拟`createTransaction()`。
Pojo pojo = new Pojo("field1Value", "field2Value");
when(serviceClass.createTransaction(pojo, /*other fields*/)).thenReturn(any());
最后一点。您可以使用WhiteBox来模拟构造函数:
Pojo pojo = new Pojo("field1Value", "field2Value");
Whitebox.setInternalState(anInjectMock, "pojo", pojo);
但然后您需要添加WhiteBox的依赖:
<!-- https://mvnrepository.com/artifact/org.powermock/powermock-reflect -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-reflect</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
I've provided the translated code portion as requested.
英文:
If I understood correctly you need to mock parameters inside the object. I think you can easily mock this parameters with when()
@ExtendWith(MockitoExtension.class)
class AnInjectMockTest {
@InjectMocks
private AnInjectMock anInjectMock;
@Mock
private ServiceClass serviceClass;
@Mock
private Param1 param1;
@Mock
private Param2 param2;
@Test
public void myTest() {
when(param1.getField1()).thenReturn(any());
when(param2.getField2()).thenReturn(any());
anInjectMock.createTransaction(pojo, /*other fields*/};
}
}
By the way, why do you need to mock it? Maybe it's better to create an object from pojo and then mock createTransaction()
Pojo pojo = new Pojo("field1Value", "field2Value");
when(serviceClass.createTransaction(pojo, /*other fields*/)).thenReturn(any());
And the last point. You can mock constructors with WhiteBox like:
Pojo pojo = new Pojo("field1Value", "field2Value");
Whitebox.setInternalState(anInjectMock, "pojo", pojo);
But then you need to add dependency for WhiteBox:
<!-- https://mvnrepository.com/artifact/org.powermock/powermock-reflect -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-reflect</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论