2016-11-26 5 views
1

Springは私のテスト環境でランダムにBeanをロードするようです。Spock統合テストでJPAリポジトリを嘲笑います。

私はUserのリポジトリのクラス次き:

@Repository 
public interface UserRepository extends JpaRepository<User, Long> { 

    User findOneByExternalId(Long externalId); 

    Optional<User> findOneById(Long id); 

} 

をし、それがテストと同等です:Deviceため

@Primary 
@Repository(value = "userRepository") 
public interface TestUserRepository extends UserRepository { 

    Long TEST_CORRECT_USER_ID = 1L; 
    Long TEST_INCORRECT_USER_ID = 2L; 

    @Override 
    default User findOneByExternalId(Long externalId) { 
     return getTestUser(externalId); 
    } 

    @Override 
    default Optional<User> findOneById(Long id) { 
     return ofNullable(getTestUser(id)); 
    } 

    default User getTestUser(Long id) { 
     if (TEST_CORRECT_USER_ID.equals(id)) { 
      User user = new User(); 
      user.setExternalId(id); 
      user.setDevices(emptyList()); 
      user.setId(id); 
      return user; 
     } 
     else { 
      return null; 
     } 
    } 

} 

と2以上:

@Repository 
public interface DeviceRepository extends JpaRepository<Device, Long> { 

    Optional<Device> findOneByDeviceId(String deviceId); 

    Optional<Device> findOneByDeviceIdAndToken(String deviceId, String token); 

} 

テストと同等:

@Primary 
@Repository(value = "deviceRepository") 
public interface TestDeviceRepository extends DeviceRepository { 

    @Override 
    default <S extends Device> S save(S device) { 
     return device; 
    } 

} 

以下の試験はDeviceRepositoryためUserRepositoryのために渡すのではなく、:

@SpringBootTest(classes = Application) 
@ContextConfiguration(classes = [TestDeviceRepository, TestUserRepository]) 
class IntegrationContextSpecTest extends Specification { 

    @Autowired 
    ApplicationContext applicationContext 

    @Unroll("Bean #bean should be instance of #clazz") 
    def "should initialize test beans instead of normal beans"() { 
     expect: 
     clazz.isAssignableFrom(applicationContext.getBean(bean). 
             getClass()) 

     where: 
     bean    | clazz 
     UserRepository | TestUserRepository 
     DeviceRepository | TestDeviceRepository 
    } 

} 

それの原因である可能性がありますか?私はapplicationContextの内容を反復しました。私のUserRepository beanは名前userRepositoryと私のDeviceRepositoryは名前deviceRepositoryを持っています。ここで

はテストからの出力です:

Condition not satisfied: 

clazz.isAssignableFrom(applicationContext.getBean(bean).getClass()) 
|  |    |     |  |  | 
|  false   |     |  |  class com.sun.proxy.$Proxy143 
|      |     |  interface com.example.repository.DeviceRepository 
|      |     org.[email protected]10e4cf09 
|      org.s[email protected]7dc51783: startup date [Sun Nov 27 22:09:16 CET 2016]; parent: org.spring[email protected]56aaaecd 
interface com.example.test.integration.mock.TestDeviceRepository 
+1

どのように失敗していますか?メッセージは何ですか? – Opal

+1

'@ Primary'アノテーションを削除するのはどうですか? –

+0

@Opal 'DeviceRepository' Beanは' TestDeviceRepository'のインスタンスではありません。私はそれが明らかだと思った、申し訳ありません!このエラーには、 'DeviceRepository'のクラスがプロキシであることについての情報があります(結局、JPAの魔法です)。 – Jezor

答えて

3

最も簡単な解決策は時々考えることが最も困難です。私は問題をあまりにも過度に思っていたことを認めます。

@Repository 
@Profile("!test") 
public interface DeviceRepository extends JpaRepository<Device, Long> { 
    /* ... implementation... */ 
} 

とテストクラスで

@Repository 
@Profile("test") 
public interface TestDeviceRepository extends DeviceRepository { 
    /* ... implementation... */ 
} 

そして今、私のすべてのテストが合格している:

私がしなければならなかったすべては@Profile、注釈などを使用しています!

関連する問題