简体   繁体   中英

How to unit test service where you have to pass bean that class is of accessibility scope? [Spock]

I tried to use a hexagonal approach wherein my domain package I have classes with view scope.

But there I faced a problem, how to mock something that I can't use because of view access.

I should @Autowire that beans but so on I realized I still can't use and pass some of them as mock's and rest as autowired bean's.

I don't think so that it is a good solution to change an access view to do tests.

So I looking to a solution how to do it in proper way. Any ideas?

Below is my example:

@Service
@RequiredArgsConstructor
public class RecipeService {

private final RecipeRepository recipeRepository; //view scope access
private final UserService userService; //public access

public Optional<Recipe> getRecipeById(Long id) {
        return recipeRepository.findById(id);
}

///////////////
@Repository
interface RecipeRepository extends JpaRepository<Recipe, Long> {
Optional<Recipe> findById(Long recipeId);
}

And test:

class RecipeServiceTest extends Specification {

private RecipeRepository recipeRepository = Mock()
private UserService userService = Mock()

void setup() {
        recipeService = new RecipeService(recipeRepository, userService)
}

In that way I received error: java.lang.IllegalAccessError: tried to access class.recipe.domain.RecipeRepository from class.recipe.service.RecipeServiceTest

[EDITED]

Below tree

└───src
    ├───main
    │   ├───java
    │   │   └───com
    │   │       └───app
    │   │           └───example
    │   │               │   
    │   │               ├───recipe
    │   │               │   ├───controller
    │   │               │   └───domain
    │   │               │           RecipeRepository.java // visible scope
    │   │               │           RecipeService.java // visible public
    └───test
        ├───groovy
        │   └───com
        │       └───app
        │           └───example
        │               ├───recipe
        │               │   ├───controller
        │               │   └───domain
        │               │           RecipeServiceTest.groovy

I would pass recipeRepository(as well as userService) as a parameter into to RecipeService, so RecipeService and RecipeRepository will not be tightly coupled. Then you can mock recipeRepository

public class RecipeService (RecipeRepository recipeRepository,UserService userService) {   
public Optional<Recipe> getRecipeById(Long id) {
        return recipeRepository.findById(id);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM