首页 文章

Mockito注入嵌套bean

提问于
浏览
0

我对mockito不是新手,但这次我在工作中发现了一个有趣的案例 . 我希望你能帮助我 .

我需要注入mock来改变测试期间的某些方法行为 . 问题是,bean结构是嵌套的,并且这个bean在其他bean中,不能从test方法访问 . 我的代码看起来像这样:

@Component
class TestedService { 
  @Autowired
  NestedService nestedService;
}

@Component
class NestedService {
  @Autowired
  MoreNestedService moreNestedService;
}

@Component
class MoreNestedService {
  @Autowired
  NestedDao nestedDao;
}

@Component
class NestedDao {
  public int method(){
    //typical dao method, details omitted
  };
}

所以在我的测试中,我希望调用NestedDao.method来返回模拟的答案 .

class Test { 
  @Mock
  NestedDao nestedDao;

  @InjectMocks
  TestedService testedSevice;

  @Test
  void test() {
    Mockito.when(nestedDao.method()).thenReturn(1);
    //data preparation omitted
    testedSevice.callNestedServiceThatCallsNestedDaoMethod();
    //assertions omitted
  }
}

我试过做一个initMocks:

@BeforeMethod
  public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

还要在我的测试类上添加注释:

@RunWith(MockitoJUnitRunner.class)

总是从方法中得到无效指针或错误的答案(不是嘲笑) .

我猜这是嵌套调用的错误,因此无法模拟这个Dao . 我也读过@InjectMocks只适用于setter或构造函数注入,我很遗憾(在私有字段上只是@Autowire),但是当我尝试时它没有用 .

有什么猜测我错过了什么? ;)

2 回答

  • 1

    这对我来说很有意义,你错了,为什么?这是因为您正在测试TestedService以及与NestedService的交互,而不是与Dao的交互,应该在NestedService测试中验证Dao交互

    看看这个:

    @Component
    class TestedService { 
    
      @Autowired
      NestedService nestedService;
    
      String sayHello(String name){
         String result = "hello" + nestedService.toUpperCase(name)
      }
    }
    
    @Component
    class NestedService {
    
      @Autowired
      MoreNestedService moreNestedService;
    
      String toUpperCase(String name){
            String nameWithDotAtTheEnd = moreNestedService.atDot(name);
            return nameWithDotAtTheEnd.toUpperCase();
    
      }
    
    }
    

    在你的测试:

    class Test { 
      @Mock
      NestedService nestedService;
    
      @InjectMocks
      TestedService testedSevice;
    
      @Test
      void test() {
        Mockito.when(nestedService.toUpperCase("rene")).thenReturn("RENE.");
        //data preparation omitted
        Assert.assertEquals("hello RENE.", testedSevice.sayHello("rene"));
        //assertions omitted
      }
    }
    

    如您所见,您假设TestedService的依赖项运行良好,您只需要验证hello是否被添加为字符串的前缀,

  • 1

    您可以使用@MockBean而不是@Mock和@InjectionMock .

    @RunWith(SpringRunner.class)
    @SpringBootTest
    class Test { 
      @MockBean
      NestedDao nestedDao;
    
      @Autowired
      TestedService testedSevice;
    
      @Test
      void test() {
        Mockito.when(nestedDao.method()).thenReturn(1);
        //data preparation omitted
        testedSevice.callNestedServiceThatCallsNestedDaoMethod();
        //assertions omitted
      }
    }
    

相关问题