Java 方法不被嘲笑

Java 方法不被嘲笑,java,unit-testing,testing,mocking,mockito,Java,Unit Testing,Testing,Mocking,Mockito,我使用Mockito来模拟一个方法,但是测试运行的是真实的方法 //Controller @RestController public class Controller { private Utils utils = new Utils(); public String myMethod(String json){ // Stuff gets done return utils.writeToKafka(topic, json, kafkat

我使用Mockito来模拟一个方法,但是测试运行的是真实的方法

//Controller
@RestController
public class Controller {

    private Utils utils = new Utils();

    public String myMethod(String json){

        // Stuff gets done
        return utils.writeToKafka(topic, json, kafkatemplate, classname);

    }
我有一个这样的测试类:

//Test
@RunWith(SpringJUnit4ClassRunner.class)
public class ControllerTest {

    @Captor
    ArgumentCaptor<String> argumentCaptor;

    @Test
    public void processOSPUpdateRequested_test(){
         Controller controller = new Controller();
         Utils utils = Mockito.spy(new Utils());
         Mockito.doReturn("myResult").when(utils).writeToKafka(anyString(), anyString(), any(), anyString());

         String topic = controller.myMethod(myString);

         //Some assertions
//测试
@RunWith(SpringJUnit4ClassRunner.class)
公共类控制器测试{
@俘虏
辩手辩手辩手;
@试验
public void processosupdaterequested_test(){
控制器=新控制器();
Utils Utils=Mockito.spy(新Utils());
Mockito.doReturn(“myResult”).when(utils).writeToKafka(anyString(),anyString(),any(),anyString());
字符串主题=controller.myMethod(myString);
//一些断言
我的writeToKafka方法签名是:

public String writeToKafka(String topic, String json, KafkaTemplate<String, String> kafkaTemplate, String classname)
公共字符串writeToKafka(字符串主题、字符串json、KafkaTemplate KafkaTemplate、字符串类名称)

但是,当我运行测试时,writeTokafka并没有被模仿!它运行的是实际的方法。为什么会发生这种情况?我遗漏了什么?

问题的症结在于:您正在
新建
一个
Utils
的实例,而您无法从测试中清楚地找到它

有两种方法可以解决这个问题——这两种方法都来自于一种哲学立场,即你是否想使用mock。这两种方法都要求你注入
Utils
,并使它成为一个bean

  • 注入
    Utils
    ,然后在测试中,注入模拟,并放弃Spring测试运行程序

    一旦你有了mock,你会想改变你的测试,不使用Spring runner,而是使用Mockito runner

    @RunWith(MockitoJUnitRunner.class)
    public class ControllerTest {
        @Mock
        private Utils utils;
    
        @InjectMocks
        private Controller testObj;
    
        // The rest of your test code
    }
    
  • Utils
    作为定义的测试范围bean注入到测试中,该bean展示了您想要测试的行为

    这有点复杂,但您可以利用Spring测试运行程序。我将此作为读者的练习(基本上,一旦您编写了
    Utils
    bean,为测试编写另一个bean并不困难)


  • 您的控制器有自己的
    utils
    实例。它没有您发现的实例。@khelwood那么这里的好做法是什么?使用单例模式?依赖项注入通常用于解决此类问题。通常您不会让控制器实例化
    utils
    本身:它将从som获得它您可以访问的位置,以便替换它。