我有一个看起来像这样的测试类:
@SpringApplicationConfiguration(classes = RecipesApplicationTest.class) // This test class will configure its own context
@ComponentScan("com.mysmartfridge.domain.recipes") // Scan recipes domain package so that domain services are available
@Import(RecipesApplication.class) // Load the bean that we want to test.
public class RecipesApplicationTest {
@ClassRule
public static final SpringClassRule SCR = new SpringClassRule();
@Rule
public final SpringMethodRule SMR = new SpringMethodRule();
@Autowired
private RecipesRepository recipesRepository;
private final RecipesRepository recipesRepositoryMock = Mockito.mock(RecipesRepository.class); // final mocks because they are given to spring context.
// Get the service to test from the context
@Autowired
RecipesApplication recipesApplication;
@Test
public void addingARecipeShouldMakeItAvailableInRandomRecipes() {
//given
RecipeDto dto = new RecipeDto();
dto.title="test";
dto.ingredients = new ArrayList<>();
dto.steps = new ArrayList<>();
final List<Recipe> recipesInMock = new ArrayList<>();
Mockito.when(recipesRepository.save(Mockito.any(Recipe.class))).thenAnswer(new Answer<Recipe>() {
@Override
public Recipe answer(InvocationOnMock aInvocation) throws Throwable {
Recipe arg = aInvocation.getArgumentAt(0, Recipe.class);
recipesInMock.add(arg);
return arg;
}
});
Mockito.when(recipesRepository.findAll()).thenAnswer(new Answer<List<Recipe>>() {
@Override
public List<Recipe> answer(InvocationOnMock aInvocation) throws Throwable {
return recipesInMock;
}
});
//when
dto = recipesApplication.createRecipe(dto);
RecipeDto randomDto = recipesApplication.findRandomRecipe();
//then
Assertions.assertThat(randomDto).isEqualTo(dto);
}
// Inject the recipeRepository mock in the context
@Bean
RecipesRepository recipesRepository() {
return recipesRepositoryMock;
}
}
我的问题是recipesRepositoryMock和recipesRepository这两个字段不是同一个对象。因此,如果我在设置我的答案时尝试用recipesRepositoryMock替换recipesRepository(即如果我when(recipesRepositoryMock.save()).thenAnswer(...)
),则它不起作用,则永远不会调用自定义答案。
我希望能够摆脱@Autowired recipesRepository,它与recipesRepositoryMock有点重复......
是不是因为我的bean周围添加了一个代理?
答案 0 :(得分:2)
你可以更好地删除
private final RecipesRepository recipesRepositoryMock = Mockito.mock(RecipesRepository.class);
如果你想模拟一个Spring bean,那么你必须使用@Autowired
为Spring创建它。
所以你的测试看起来像:
@SpringApplicationConfiguration(classes = RecipesApplicationTest.class) // This test class will configure its own context
@ComponentScan("com.mysmartfridge.domain.recipes") // Scan recipes domain package so that domain services are available
@Import(RecipesApplication.class) // Load the bean that we want to test.
public class RecipesApplicationTest {
@ClassRule
public static final SpringClassRule SCR = new SpringClassRule();
@Rule
public final SpringMethodRule SMR = new SpringMethodRule();
@Autowired
private RecipesRepository recipesRepository;
// Get the service to test from the context
@Autowired
RecipesApplication recipesApplication;
@Test
public void addingARecipeShouldMakeItAvailableInRandomRecipes() {
// your test
}
// Inject the recipeRepository mock in the context
@Bean
RecipesRepository recipesRepository() {
return Mockito.mock(RecipesRepository.class);
}
}
答案 1 :(得分:0)
听起来您正在尝试依赖自动连接,以便Spring正确地将RecipesRepository
实例作为依赖项注入RecipesApplication
。 This question似乎与你的相似。话虽这么说,我因为你可能没有使用像[ReflectionTestUtils][2]
这样的东西而犹豫不决。相反,请尝试删除recipesRepository
中的RecipesApplicationTest
字段,并保留recipesRepositoryMock
字段。但是,在dto = recipesApplication.createRecipe(dto)
行之前,请尝试查看是否可以通过recipesRepositoryMock
等类似的调用将recipesApplication
手动注入recipesApplication.setRecipesRepository(recipesRepositoryMock)
。