【问题标题】:why cannot we create spy for Parameterized Constructor using Mockito为什么我们不能使用 Mockito 为参数化构造函数创建间谍
【发布时间】:2017-08-04 20:20:11
【问题描述】:

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

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

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

【问题讨论】:

    标签: java mockito junit4


    【解决方案1】:

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

    假设你的主类是A。其中BC 是它的依赖项

    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
    
    1. 这里的BC 是您使用参数化构造函数注入到您的类A 中的模拟对象。
    2. 然后我们创建了A 中的spy,称为spyA
    3. 我们通过修改类A 中受保护方法method2 的返回值来检查spy 是否真的在工作,如果spyA 不是A 的实际spy,这是不可能的.

    【讨论】:

    • 我收到了thenReturn() may be missing
    • 如果我只想监视该类,并将参数实例化为真实对象怎么办?
    • @user2386301 在构造函数中应该仍然可行吧?
    【解决方案2】:

    听起来您可能缺少依赖注入解决方案。 Mockito 非常适合与您的 DI 一起注入模拟。例如,您可以使用 CDI,用 @Inject 注释您的 NotificationEntryService 成员,在您的测试中为两者声明 @Mocks,然后让 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());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多