希望 spring bean 具有模拟和真实实现+spring+mockito
Want spring bean to have mocked as well as real implementations+spring+mockito
我有一个 class Service
想要测试。基本上,我遇到了一个问题,因为我希望 Service
对象被部分模拟。只有 obj1
应该被嘲笑,其他合作者应该是真实的。我的代码类似于:
@Component
public class Service {
@Autowired
Object1 obj1;
@Autowired
Object2 obj2;
public void validate(){
obj1.isValid();
obj2.isActive();
}
}
现在在测试上述 Service
class 的验证方法时,我想在调用 obj2
[=25= 的实际实现时模拟 obj1.isValid()
方法]
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:conf/test-context.xml"})
public class ServiceTest {
@InjectMocks
Service service;
@Mock
OBject1 obj1;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testValidate (){
service.validate();
//assert and other stuff
}
}
这个测试失败了,当我调试验证方法时,我发现 obj1
实例被注入了 Service
class 中预期的模拟,但是 obj2
被注入了作为 null
。因此测试失败...
有什么办法可以做到这一点吗?
更新
当我阅读一些 SO 答案时,我使用了 springockito。我将下面的东西添加到测试 class 中,如下所示,但结果仍然相同:
@ReplaceWithMock
@Autowired
Object2 obj2
这可以通过 @Spy
实现
您的代码应如下所示
public class ServiceTest {
@InjectMocks
Service service;
@Mock
OBject1 obj1;
@Spy
Object obj2 = new SomeObject("argument");
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
}
您必须将 @Autowired
注释添加到 service
对象,以便正常注入 service
中的所有其他属性,并为模拟类型注入模拟对象。
在下面的示例中,Class2
的普通 bean 将被注入 service
,但是 @InjectMocks
注释将注入 Class1
的模拟对象。
服务:
@Component
public class Service
{
@Autowired
private Class1 class1;
@Autowired
private Class2 class2;
public Class1 getClass1()
{
return class1;
}
public Class2 getClass2()
{
return class2;
}
}
Class1:
@Component
public class Class1
{
public String getName()
{
return "Class1";
}
}
Class2:
@Component
public class Class2
{
public String getName()
{
return "Class2";
}
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"classpath:application-context.xml"
})
public class ServiceTest
{
@Mock
private final Class1 class1 = Mockito.mock(Class1.class);
@InjectMocks
@Autowired
private Service service;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
}
@Test
public void test()
{
Mockito.when(class1.getName()).thenReturn("MockClass1");
Assert.assertNotNull(service);
Assert.assertEquals("MockClass1", service.getClass1().getName());
Assert.assertNotNull("Class2", service.getClass2().getName());
}
}
实现此目的的另一种方法是使用 springocito。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class,locations={"classpath:conf/test-context.xml"})
public class ServiceTest
{
@ReplaceWithMock
@Autowired
private Object1 object1
@Autowired
private Service service;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
}
@Test
public void test()
{
//assert stuff
}
}
服务将得到正确填充,但对象 1 除外,它将模拟 instance.Rest 所有自动装配的内部 bean。
不要使用 Autowired 和 InjectMocks。这是不好的做法。您可以同时使用 @InjectMocks 和 @Spy 来模拟真实对象并允许在这个间谍对象内部进行模拟
我有一个 class Service
想要测试。基本上,我遇到了一个问题,因为我希望 Service
对象被部分模拟。只有 obj1
应该被嘲笑,其他合作者应该是真实的。我的代码类似于:
@Component
public class Service {
@Autowired
Object1 obj1;
@Autowired
Object2 obj2;
public void validate(){
obj1.isValid();
obj2.isActive();
}
}
现在在测试上述 Service
class 的验证方法时,我想在调用 obj2
[=25= 的实际实现时模拟 obj1.isValid()
方法]
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:conf/test-context.xml"})
public class ServiceTest {
@InjectMocks
Service service;
@Mock
OBject1 obj1;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testValidate (){
service.validate();
//assert and other stuff
}
}
这个测试失败了,当我调试验证方法时,我发现 obj1
实例被注入了 Service
class 中预期的模拟,但是 obj2
被注入了作为 null
。因此测试失败...
有什么办法可以做到这一点吗?
更新 当我阅读一些 SO 答案时,我使用了 springockito。我将下面的东西添加到测试 class 中,如下所示,但结果仍然相同:
@ReplaceWithMock
@Autowired
Object2 obj2
这可以通过 @Spy
实现您的代码应如下所示
public class ServiceTest {
@InjectMocks
Service service;
@Mock
OBject1 obj1;
@Spy
Object obj2 = new SomeObject("argument");
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
}
您必须将 @Autowired
注释添加到 service
对象,以便正常注入 service
中的所有其他属性,并为模拟类型注入模拟对象。
在下面的示例中,Class2
的普通 bean 将被注入 service
,但是 @InjectMocks
注释将注入 Class1
的模拟对象。
服务:
@Component
public class Service
{
@Autowired
private Class1 class1;
@Autowired
private Class2 class2;
public Class1 getClass1()
{
return class1;
}
public Class2 getClass2()
{
return class2;
}
}
Class1:
@Component
public class Class1
{
public String getName()
{
return "Class1";
}
}
Class2:
@Component
public class Class2
{
public String getName()
{
return "Class2";
}
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"classpath:application-context.xml"
})
public class ServiceTest
{
@Mock
private final Class1 class1 = Mockito.mock(Class1.class);
@InjectMocks
@Autowired
private Service service;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
}
@Test
public void test()
{
Mockito.when(class1.getName()).thenReturn("MockClass1");
Assert.assertNotNull(service);
Assert.assertEquals("MockClass1", service.getClass1().getName());
Assert.assertNotNull("Class2", service.getClass2().getName());
}
}
实现此目的的另一种方法是使用 springocito。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class,locations={"classpath:conf/test-context.xml"})
public class ServiceTest
{
@ReplaceWithMock
@Autowired
private Object1 object1
@Autowired
private Service service;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
}
@Test
public void test()
{
//assert stuff
}
}
服务将得到正确填充,但对象 1 除外,它将模拟 instance.Rest 所有自动装配的内部 bean。
不要使用 Autowired 和 InjectMocks。这是不好的做法。您可以同时使用 @InjectMocks 和 @Spy 来模拟真实对象并允许在这个间谍对象内部进行模拟