Java 在类的构造函数中模拟方法

Java 在类的构造函数中模拟方法,java,junit,constructor,mockito,Java,Junit,Constructor,Mockito,我是莫基托的新手。假设我有一节这样的课 public class MyClass { int a; String b; public MyClass(int a) { this.a = a; this.b = draw(); System.out.println("class is created"); } public String draw() { System.out.println(

我是莫基托的新手。假设我有一节这样的课

public class MyClass {
    int a;
    String b;
    public MyClass(int a) {
        this.a = a;
        this.b = draw();
        System.out.println("class is created");
    }

    public String draw() {
        System.out.println("my");
        return "b";
    }

    public void apple() {
        System.out.println("apple");
    }
}

我正在使用Mockito编写一个JUnit测试,其中我正在使用构造函数创建类的对象。当我安装类时,是否可以模拟draw()方法?

不清楚为什么需要这里的
Mockito
。这是一个没有
Mockito
的解决方案

在测试中,使用重写的
draw()
方法创建
MyClass
的实例:

final MyClass myClass = new MyClass() {
    @Override
    public String draw() {
        return "mock data";
    }
}

// Now test your class as you want

不清楚为什么需要此处的
Mockito
。这是一个没有
Mockito
的解决方案

在测试中,使用重写的
draw()
方法创建
MyClass
的实例:

final MyClass myClass = new MyClass() {
    @Override
    public String draw() {
        return "mock data";
    }
}

// Now test your class as you want

使用Mockito测试类的一种方法是

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

public class TestMyClass {

    @Mock
    private MyClass clazz;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testDraw() {
        when(clazz.draw()).thenReturn("My mock hello");
        assertEquals("My mock hello", clazz.draw());
    }
}

使用Mockito测试类的一种方法是

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

public class TestMyClass {

    @Mock
    private MyClass clazz;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testDraw() {
        when(clazz.draw()).thenReturn("My mock hello");
        assertEquals("My mock hello", clazz.draw());
    }
}
您可以使用间谍进行部分模拟(有关如何进行模拟的信息,请参阅)

但和往常一样:当人们开始考虑使用mocking框架的复杂方法时,真正的答案是:后退一步,改进生产代码。构造函数应该只做简单的初始化操作

在您的情况下,一种合理的方法是:不要调用内部方法来计算该字段的值,而是将该值传递给构造函数(换句话说,使用依赖注入)

你仍然可以这样做:

public MyClass(int a) {
  this(a, draw());
}

MyClass(int a, String b) { 
  this.a = a; ...
现在,您的单元测试可以很高兴地使用包含两个参数的ctor,而您对模拟任何东西的需求都将完全消失。

您可以使用SPIE进行部分模拟(请参阅以了解如何做到这一点)

但和往常一样:当人们开始考虑使用mocking框架的复杂方法时,真正的答案是:后退一步,改进生产代码。构造函数应该只做简单的初始化操作

在您的情况下,一种合理的方法是:不要调用内部方法来计算该字段的值,而是将该值传递给构造函数(换句话说,使用依赖注入)

你仍然可以这样做:

public MyClass(int a) {
  this(a, draw());
}

MyClass(int a, String b) { 
  this.a = a; ...

现在,您的单元测试可以很高兴地使用包含两个参数的ctor,您对模拟任何东西的需求都会完全消失。

您可以分享您的测试代码,或者至少是它的相关部分吗?您试图实现什么?被测试的类对另一个对象没有任何依赖关系。所以没有什么可以嘲笑的。你不必总是使用mockito。你为什么要嘲笑任何事。使用简单的junit测试。因为您正在编写测试,所以您的目标可能是编写可测试的代码。如果是这样,您应该避免构造函数做更多的事情,而不仅仅是给字段分配参数。有关此主题的精彩论证,请参阅。您可以分享您的测试代码,或者至少是测试的相关部分吗?您想实现什么?被测试的类对另一个对象没有任何依赖关系。所以没有什么可以嘲笑的。你不必总是使用mockito。你为什么要嘲笑任何事。使用简单的junit测试。因为您正在编写测试,所以您的目标可能是编写可测试的代码。如果是这样,您应该避免构造函数做更多的事情,而不仅仅是给字段分配参数。请参阅,以获取关于此主题的优秀论证。然后再次模拟被测类,然后再次模拟被测类