Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我们不能使用Mockito为参数化构造函数创建spy_Java_Mockito_Junit4 - Fatal编程技术网

Java 为什么我们不能使用Mockito为参数化构造函数创建spy

Java 为什么我们不能使用Mockito为参数化构造函数创建spy,java,mockito,junit4,Java,Mockito,Junit4,我的代码中只有参数化构造函数,我需要通过它进行注入 我想监视参数化构造函数,将模拟对象作为junit的依赖项注入 public RegDao(){ //original object instantiation here Notification .... EntryService ..... } public RegDao(Notification notification , EntryService entry) { // initialize here } we have som

我的代码中只有参数化构造函数,我需要通过它进行注入

我想监视参数化构造函数,将模拟对象作为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);

但是我们有什么东西可以在构造函数中注入模拟对象并监视它吗?

听起来您可能缺少依赖项注入解决方案。Mockito非常适合与DI一起注入Mock。例如,您可以使用CDI,用
@Inject
注释
通知
入口服务
成员,在测试中为这两个成员声明
@Mock
s,然后让Mockito将它们注入
RegDao
进行测试

以下是我认为您正在尝试运行的测试的工作模型:

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());
    }
}

您可以通过在junit中用参数化构造函数实例化主类,然后从中创建一个间谍来实现这一点

假设您的主类是
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;
    }
}
然后可以使用参数化类为此编写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();
    }
}
测试类的输出

A's method called
20
  • 这里
    B
    C
    是模拟对象,您使用参数化构造函数将它们注入类
    A
  • 然后我们创建了一个名为
    spyA
    spy
    a
  • 我们通过修改类
    a
    中受保护方法
    method2
    的返回值来检查
    spy
    是否真的起作用,如果
    spyA
    不是
    a
    的实际
    spy
    ,这是不可能的

  • 我得到了
    thenReturn()可能丢失了
    如果我只想监视该类,并且我将参数实例化为真实对象,该怎么办?@user2386301在构造函数中应该仍然可行,对吗?