Java 莫基托+;间谍:如何收集返回值

Java 莫基托+;间谍:如何收集返回值,java,mockito,spy,Java,Mockito,Spy,我得到了一个使用工厂创建对象的类。 在单元测试中,我希望访问工厂的返回值。 因为工厂直接传递给类,并且没有为创建的对象提供getter,所以我需要截获从工厂返回的对象 RealFactory factory = new RealFactory(); RealFactory spy = spy(factory); TestedClass testedClass = new TestedClass(factory); // At this point I would lik

我得到了一个使用工厂创建对象的类。 在单元测试中,我希望访问工厂的返回值。 因为工厂直接传递给类,并且没有为创建的对象提供getter,所以我需要截获从工厂返回的对象

RealFactory factory     = new RealFactory();
RealFactory spy         = spy(factory);
TestedClass testedClass = new TestedClass(factory);

// At this point I would like to get a reference to the object created
// and returned by the factory.
是否有可能访问工厂的返回值?可能在使用间谍?

我能看到的唯一方法是模拟factory create方法。

标准模拟方法是:

  • 预创建您希望工厂在测试用例中返回的对象
  • 创建工厂的模拟(或间谍)
  • 指定模拟工厂以返回预先创建的对象

  • 如果您真的想让RealFactory动态创建对象,可以将其子类化并重写factory方法以调用
    super.create(…)
    ,然后将引用保存到测试类可访问的字段,然后返回创建的对象。

    首先,您应该将
    spy
    作为构造函数参数传入

    除此之外,以下是你可以做到的

    public class ResultCaptor<T> implements Answer {
        private T result = null;
        public T getResult() {
            return result;
        }
    
        @Override
        public T answer(InvocationOnMock invocationOnMock) throws Throwable {
            result = (T) invocationOnMock.callRealMethod();
            return result;
        }
    }
    
    公共类ResultCaptor实现应答{
    private T result=null;
    公共T getResult(){
    返回结果;
    }
    @凌驾
    公共T应答(调用锁调用锁)抛出可丢弃{
    结果=(T)invocationMock.callRealMethod();
    返回结果;
    }
    }
    
    预期用途:

    RealFactory factory     = new RealFactory();
    RealFactory spy         = spy(factory);
    TestedClass testedClass = new TestedClass(spy);
    
    // At this point I would like to get a reference to the object created
    // and returned by the factory.
    
    
    // let's capture the return values from spy.create()
    ResultCaptor<RealThing> resultCaptor = new ResultCaptor<>();
    doAnswer(resultCaptor).when(spy).create();
    
    // do something that will trigger a call to the factory
    testedClass.doSomething();
    
    // validate the return object
    assertThat(resultCaptor.getResult())
            .isNotNull()
            .isInstanceOf(RealThing.class);
    
    RealFactory工厂=新的RealFactory();
    RealFactory spy=间谍(工厂);
    TestedClass TestedClass=新的TestedClass(spy);
    //在这一点上,我希望获得对所创建对象的引用
    //并由工厂返回。
    //让我们从spy.create()捕获返回值
    ResultCaptor ResultCaptor=新的ResultCaptor();
    doAnswer(resultCaptor).when(spy.create();
    //做一些会触发打电话到工厂的事情
    测试类。doSomething();
    //验证返回对象
    assertThat(resultCaptor.getResult())
    .isNotNull()
    .isInstanceOf(房地产类);
    
    为什么
    TestedClass
    应该将工厂作为依赖项。它不应该只要求工厂创建实际的类吗?(德米特定律)
    TestedClass
    是一个OSGi组件。组件的方法要求每次调用由工厂创建的新对象。我将对象创建重构为一个工厂类,以提供更好的可测试性。由于创建的对象根据方法参数进行初始化,因此无法简单地传入创建的对象而不是工厂。谢谢分享。IMHO:这应该是公认的答案。这是返回结果的副本还是相同的实例?它将返回相同的实例Hanks Jeff,这真的很有用这似乎是我希望成为Mockito的一部分。这是可行的,但如果我们必须这样测试,这可能是一个糟糕的设计?间谍医生向我暗示了这个方向。有人有什么想法吗?