如何模拟@Autowire对象的依赖关系?

时间:2020-09-08 00:11:36

标签: java spring spring-boot unit-testing autowired

我有一个@Autowire对象,其中包含需要模拟其方法调用的字段。

在主类中:

@Component
public class Pizza {
     private Tomato tomato;
     private Cheese cheese;

     @Autowired
     private Pizza(Tomato tomato, Cheese cheese) {
        this.tomato = tomato;
        this.cheese = cheese;
     }
     
     public String arrangePizza(tomato, cheese) {
        Sauce sauce = tomato.createSauce();
        combine(sauce, cheese);
        return "Pizza created!"
     }
}

在测试课中:

@RunWith(SpringRunner.class)
public class TestPizza {
     @Autowire
     private Pizza pizza;

     //probably create instances of cheese and tomato here?


     private void testCreatePizza {
        //here I want to mock tomato.createSauce()
        pizza.arrangePizza(tomato, cheese);
     }
}

我正在尝试使用Mockito或EasyMock在testCreatePizza中模拟方法Tomato.createSauce(),但由于Pizza是自动装配的,因此我不确定如何执行此操作。我是否需要在测试类中创建tomatocheese的Autowire实例? spring是否会自动知道将构造函数设置为这些实例?

2 个答案:

答案 0 :(得分:1)

Mockito提供@Mock批注以模拟对象,并提供@InjectMocks批注以将这些模拟项注入自动装配的字段中。

@RunWith(SpringRunner.class)
@ExtendWith(MockitoExtension.class)
public class TestPizza {

     @Mock
     private Tomato tomato;

     @Mock
     private Cheese cheese;        

     @InjectMocks
     private Pizza pizza;

     @BeforeEach
     void init() {
         MockitoAnnotations.initMocks(this);
         when(tomato.createSauce()).thenReturn("Spicy Sauce");
     }

     @Test
     private void testCreatePizza {
        pizza.createPizza(tomato, cheese);
     }
}

答案 1 :(得分:1)

由于这是标记为spring-boot的,因此还应该指出@MockBean annotation。 (相关报价:“在上下文中定义的任何现有的相同类型的单个Bean都将被该模拟替换。如果未定义现有的Bean,则将添加一个新的Bean。”)

这意味着,在您的测试课中,您可以做

@Autowired
private Pizza pizza;

@MockBean
private Tomato tomato;

,然后像平常一样使用Mockito的when等。与其他答案相比,这种方式可以为您节省一两个注释(如果您要嘲笑多件事)以及对initMocks()的调用。

相关问题