mockito 如何模拟对象从方法返回?

aelbi1ox  于 2022-12-04  发布在  其他
关注(0)|答案(3)|浏览(201)

我想模拟对象A aB.foo()返回。
我试过用@Mock模拟A,但没有成功。
第一个
我怎么能嘲笑A呢?

hs1ihplo

hs1ihplo1#

class SomeClass {
    public void doSomeThing() {
        B b = new B();
        A a = b.foo();
        a.foo();
    }
}

由于您的代码创建了B类的新示例,因此不可能模拟所述对象的行为。SomeClassB紧密耦合,并且SomeClass依赖于B的具体实现。
你可以重构你的类使之成为可测试的。要做到这一点,允许你的类的消费者注入如何创建B的行为。一个可能的解决方案是:

class SomeClass {
  private final Supplier<? extends B> bFactory;
  public SomeClass(final Supplier<? extends B> bFactory) {
    this.bFactory = bFactory;
  }

  // Production code can use the parameterless constructor to get the old behavior
  // But this is mostly to help with migration, real code should use the parameterized constructor too
  public SomeClass() {
    this(B::new);
  }

  public void doSomeThing() {
    B b = this.bFactory.get();
    A a = b.foo();
    a.foo();
  }
}

现在你可以注入一个提供者,它在你的测试中提供你的类的一个模拟示例:

@Test
void test() {
  final A aMock = mock(A.class);
  when(aMock.foo()).thenAnswer(a -> /* ... */);
  final B bMock = mock(B.class);
  when(bMock.foo()).thenReturn(aMock);
  final SomeClass someClass = new SomeClass(() -> bMock);
  assertDoesNotThrow( () -> someClass.doSomeThing() );
}

请注意,通常认为让模拟返回模拟是不好的做法。这样的设置会使您的测试脆弱、不必要的复杂,并且与实现耦合。
Why is mocking static method with Mockito not working in my case?后找到详尽的问题陈述和替代解决方案

xn1cxnb4

xn1cxnb42#

试试这个@模拟B b;
如果b.foo。

jecbmhm3

jecbmhm33#

必须调用openMocks(this)方法来初始化带注解的对象。
请参阅Annotation Type Mock
因此,测试类应如下所示:

public class SomeClassTest {
    @Mock
    A a;

    @InjectMocks
    SomeClass someClass;

    private AutoCloseable closeable;

    @BeforeEach
    public void openMocks() {
        closeable = MockitoAnnotations.openMocks(this);
    }

    @AfterEach
    public void releaseMocks() throws Exception {
        closeable.close();
    }

    @Test
    void test() {
        Mockito.when( a.foo() ).thenReturn(true);
        Assertions.assertDoesNotThrow( () -> someClass.doSomeThing() );
    }
}

相关问题