Mockito: 当任何实例调用方法时,thenReturn something

huangapple go评论71阅读模式
英文:

Mockito: When any instance invokes method, thenReturn something

问题

以下是您要翻译的内容:

我对Mockito非常陌生,有一个类似这样的类:

    public class A {
       private B b;
       public B getB() { return b; }
       // ...
    }


    public class B {
       private C c;
       public C getC() { return c; }
       // ...
    }

我正在使用Mockito为类A编写单元测试,并尝试实现以下行为,其中B是一个模拟对象:

    when(a.getB().getC()).thenReturn(mock(C.class))
    when(any(mock(C.class)).doSomething()).thenReturn("somethingElse") // 这不起作用。

如何在任何模拟的C类实例调用doSomething()时返回"somethingElse"?我不想将此行为绑定到任何一个特定的mock(C.class)实例。

请注意,我已经将HTML编码(例如")还原为正常的引号。如果您需要进一步的帮助,请告诉我。

英文:

I'm very new to Mockito and have a class like

public class A {
   private B b;
   public B getB() { return b; }
   // ...
}

and

public class B {
   private C c;
   public C getC() { return c; }
   // ...
}

I am writing unit tests using Mockito for class A, and trying to achieve the following behavior, where B is a mock:

when(a.getB().getC()).thenReturn(mock(C.class))
when(any(mock(C.class)).doSomething()).thenReturn("somethingElse") // This doesn't work.

How can I return "somethingElse" when any mocked instance of C calls doSomething()? I don't want to bind this behavior to any one particular mock(C.class) instance.

答案1

得分: 1

以下是翻译好的部分:

首先,您必须将测试对象视为一个单元,并模拟其他一切。所以,因为您正在测试类A,您不能模拟A的方法。

这是如何使用Mockito使用注解来模拟B实例的方法:

@MockitoSettings
public class ATest {
  @Mock
  private B b;
  @InjectMocks
  private A a;

  @Test
  void testExample() {
    C c = mock(C.class);
    when(b.getC()).thenReturn(c);
    when(c.doSomething()).thenReturn("somethingElse");

    // a.getB() == b
  }
}

那么这里发生了什么呢?

注解@Mock正在初始化一个类型为B的模拟对象,并将字段变量b设置为它。

@InjectMocks正在收集所有@Mock字段,并设置对象中的字段。这是您的测试对象。

现在,您的A实例有一个模拟的B对象。而在B内部,还有一个C。由于B是一个模拟对象,方法getC()实际上什么都不做。您必须为它设置一些功能。在测试中,我初始化了一个本地的模拟C实例,以便从getC()返回。

因此,现在当A对象访问模拟的B并获取C时,它将获得这个本地变量c以供使用。因此,您可以为这个对象设置模拟函数。

英文:

First of all, you have to treat your test subject as a unit, and mock everything else. So since you're testing class A you cannot mock As methods.

Here's how you would use Mockito to mock the instance of B using annotations:

@MockitoSettings
public class ATest {
  @Mock
  private B b;
  @InjectMocks
  private A a;

  @Test
  void testExample() {
    C c = mock(C.class):
    when(b.getC()).thenReturn(c);
    when(c.doSomething()).thenReturn("somethingElse");
    
    // a.getB() == b
  }
}

So what is happening here?

The annotation @Mock is intializing a mocked object of type B and setting the field variable b to it.

@InjectMocks is collecting all @Mock fields and setting the fields in the object. This is your test subject.

Now your A instance has a mocked B object. And within B you have C. Since B is a mocked object the method getC() doesn't do anthing at all. You have to stub it with some functionality. In the test, I've initialized a local mocked C instance to be returned from getC().

So now when A object accesses the mocked B and get C it will get this local variable c to use. So you can stub this object with mocked functions.

答案2

得分: 0

不要添加mock(),它用于创建新的模拟对象。

像这样:

when(any(C.class).doSomething()).thenReturn("somethingElse");
英文:

Do not add the ```mock()`` its used for creating new mocks.

Like this

when(any(C.class).doSomething()).thenReturn("somethingElse");

huangapple
  • 本文由 发表于 2020年8月6日 02:29:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63271430.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定