簡體   English   中英

在Spring應用程序上下文中注入模擬對象會創建一個副本

[英]Injecting a mock in Spring application context creates a copy

我有一個看起來像這樣的測試類:

@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周圍添加了代理嗎?

您最好刪除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);
  }

}

聽起來您正在嘗試依賴自動RecipesRepository以便Spring正確地將RecipesRepository實例作為依賴項注入RecipesApplication 這個問題似乎與您的相似。 話雖這么說,我很想聲明一個重復項,因為您可能沒有使用[ReflectionTestUtils][2]類的東西。 相反,嘗試僅刪除recipesRepository中的recipesRepository字段, RecipesApplicationTest保留recipesRepositoryMock字段。 但是,在dto = recipesApplication.createRecipe(dto)行之前,請嘗試查看是否可以通過諸如recipesApplication.setRecipesRepository(recipesRepositoryMock)類的調用手動將recipesRepositoryMock注入recipesApplication

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM