java 不传入模拟对象的模拟行为Mockito

r6l8ljro  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(198)

我有一个Java类和方法,我想用Mockito测试。这些类在它们的构造函数或其他方法中将构造对象,然后在其他方法中使用这些对象。
我想模拟那些被使用的对象的行为。重要的是这些对象都没有被传递到类中。相反,它们是在类本身中生成的。例如,假设这是我的一个类:

private Client someClient;

public MyClass() {
    this.someClient = setupClient();
}

private setupClient() {...}

public methodIWantToTest() {
    this.someClient.makeApiCall(String requestString);
    // do stuff
}

在我的测试类和测试中,我希望能够做到以下几点:

// test class
...
MyClass classImGoingToTest; 

@Test
public void testMethodIWantToTest() {
    Mockito.when(Client.class).makeApiCall(Mockito.anyString()).thenDoSomething();
    ...
}

当然,Mockito需要让基本的事情变得令人沮丧地困难。那么,如何在Mockito做到这一点呢?
我读到的其他答案要么是“使用powermockito”,我现在想避免,要么是“你不应该测试这个”,这不是我问题的答案,或者他们说“你应该传入值”,正如我上面解释的那样,这是不可能的。

rxztt3cl

rxztt3cl1#

您需要将MyClass作为一个 Package 器类,并且不测试它,这是可以的,因为它将是微不足道的:

class MyClass {
  private final MyTestableClass myTestableClass;

  public MyClass() {
    myTestableClass = new MyTestableClass(setupClient());
  }

  public void methodIWantToTest() {
    myTestableClass.methodIWantToTest();
  }
}

然后,您可以为MyTestableClass编写单元测试,将mock Client传递给它的构造函数。
(of当然setupClient()并不简单,但是在您最初的测试中并没有测试它。)

camsedfj

camsedfj2#

在依赖类中配置依赖项可能会有问题。根据系统的复杂性,您可能希望探索依赖项注入。忽略这一点。
提供一个包含依赖项作为参数的替代构造函数。

public class MyClass {
  private Client someClient;

  public MyClass() {
    this(setupClient());
  }
  protected MyClass(Client client) {
    this.someClient = client;
  }

  private Client setupClient() {...}

  public methodIWantToTest() {
    this.someClient.makeApiCall(String requestString);
    // do stuff
  }
  ...
}

在测试中定义mock并将其作为参数传递给构造函数。

public class MyClassTest {
  private MyClass SUT;
  // Dependencies
  private Client client = Mockito.mock(Client.class);

  @Before
  public void beforeTest() {
    SUT = new MyClass(client);
  }

  @Test
  public void testMethodIWantToTest() {
    Mockito.when(client.makeApiCall(Mockito.anyString())).thenDoSomething();
    .. test stuff
  }
}

相关问题