java 为什么我们不能使用 Mockito 为参数化构造函数创建间谍
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45514907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
why cannot we create spy for Parameterized Constructor using Mockito
提问by Pradeep
I have only parameterized constructor in my code and i need to inject through it.
我的代码中只有参数化构造函数,我需要通过它注入。
I want to spy parameterized constructor to inject mock object as dependency for my junit.
我想监视参数化构造函数来注入模拟对象作为我的 junit 的依赖项。
public RegDao(){
//original object instantiation here
Notification ....
EntryService .....
}
public RegDao(Notification notification , EntryService entry) {
// initialize here
}
we have something like below :
RegDao dao = Mockito.spy(RegDao.class);
But do we have something that i can inject mocked object in the Constructor and spy it?.
但是我们有什么东西可以在构造函数中注入模拟对象并监视它吗?
回答by Dhawal Kapil
You can do that by instantiating your main class with parametrized constructor in your junit and then creating a spy from it.
您可以通过在 junit 中使用参数化构造函数实例化主类,然后从中创建间谍来做到这一点。
Let's suppose your main class is A
. Where B
and C
are its dependencies
假设您的主要课程是A
. 在哪里B
和C
在它的依赖
public class A {
private B b;
private C c;
public A(B b,C c)
{
this.b=b;
this.c=c;
}
void method() {
System.out.println("A's method called");
b.method();
c.method();
System.out.println(method2());
}
protected int method2() {
return 10;
}
}
Then you can write junit for this using your parametrized class as below
然后你可以使用你的参数化类为此编写junit,如下所示
@RunWith(MockitoJUnitRunner.class)
public class ATest {
A a;
@Mock
B b;
@Mock
C c;
@Test
public void test() {
a=new A(b, c);
A spyA=Mockito.spy(a);
doReturn(20).when(spyA).method2();
spyA.method();
}
}
Output of test class
测试类的输出
A's method called
20
- Here
B
andC
are mocked object that you injected in your classA
using parametrized constructor. - Then we created a
spy
ofA
calledspyA
. - We checked if
spy
is really working by modifying the return value of a protected methodmethod2
in classA
which could not have been possible ifspyA
was not an actualspy
ofA
.
- 这里
B
和C
是您A
使用参数化构造函数注入到类中的模拟对象。 - 然后,我们创建了一个
spy
的A
叫spyA
。 - 我们检查,如果
spy
真的通过修改保护方法的返回值工作method2
在课堂上A
可能不会有可能的,如果spyA
是不实际spy
的A
。
回答by Isaac Truett
It sounds like you might be missing a dependency injection solution. Mockito is great for working with your DI to inject mocks. For example, you can use CDI, annotation your Notification
and EntryService
members with @Inject
, declare @Mock
s for both in your test, and then let Mockito inject those into your RegDao
for testing.
听起来您可能缺少依赖注入解决方案。Mockito 非常适合与您的 DI 一起注入模拟。例如,您可以使用 CDI,使用 注释您Notification
和EntryService
成员@Inject
,@Mock
在您的测试中为两者声明s,然后让 Mockito 将它们注入您RegDao
的测试中。
Here's a working mockup of the test I think you're trying to run:
这是我认为您正在尝试运行的测试的工作模型:
import static org.junit.Assert.assertEquals;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MockitoSpyInjection {
static class Notification { }
static class EntryService { }
static class RegDao {
@Inject
Notification foo;
@Inject
EntryService bar;
public RegDao() {
}
public RegDao(Notification foo, EntryService bar) {
this.foo = foo;
this.bar = bar;
}
public Notification getFoo() {
return foo;
}
public EntryService getBar() {
return bar;
}
}
@Mock
Notification foo;
@Mock
EntryService bar;
@Spy
@InjectMocks
RegDao dao;
@Test
public void test() {
assertEquals(foo, dao.getFoo());
assertEquals(bar, dao.getBar());
}
}