Integration tests on springboot with constructor injection pattern





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I am trying to use Constructor Injection dependency pattern.



I wonder what is the correct approach to inject JPA Repositories on Integration test classes:



I have my source code:



RepoClass



@Repository
public interface MyClassRepo extends JpaRepository<MyClass, Long> {
... methods ...
}


Service following cosntructor injection



public class MyClassService {

private final MyClassRepo myClassRepo;

public DeviceServiceImpl(final MyClassRepo myClassRepo) {
this.myClassRepo = myClassRepo;
}

public boolean myMethodToTest() {
... whatever...
}
}


To test it: (Here comes my issue)



SpringRunner class OPTION 1: Constructor injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester (final MyClassRepository deviceRepository) {
this.myClassRepository = myClassRepository;
this.myClassService= new myClassService(myClassRepository);
}

}


Does not work since console output says:




Test class should have exactly one public zero-argument constructor




SpringRunner class OPTION 2: Autowired injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
@Autowired
private MyClassRepository myClassRepository;

private MyClassService myClassService = new myClassService(myClassRepository);

}



I feel like it is breaking the desired pattern.




SpringRunner class OPTION 3: Empty Constructor



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {

private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester () {
this.myClassRepository = new MyClassRepository(); // Obviously NOT working, since its an interface
this.myClassService= new myClassService(myClassRepository);
}
}



As commented: Obviously NOT working, since MyClassRepository its an interface




Is there any better approach to solve this issue?










share|improve this question























  • You could use Junit5. It allows constructors with multiple arguments.

    – pcoates
    Nov 22 '18 at 9:58











  • I don't think that the dependency injection by constructor pattern matters for tests.You're writing tests to test the functionality and the ability to do this comes first before the design patterns and so on. I don't think that any known pattern was meant for testing really. In the integration tests the context is killed when the tests are finished, so in my opinion @Autowired is the best and easiest way which I normally follow. It's not affecting your app in a bad way. But you should avoid that in the application code though.

    – Kamil Kozlowski
    Nov 22 '18 at 11:28




















0















I am trying to use Constructor Injection dependency pattern.



I wonder what is the correct approach to inject JPA Repositories on Integration test classes:



I have my source code:



RepoClass



@Repository
public interface MyClassRepo extends JpaRepository<MyClass, Long> {
... methods ...
}


Service following cosntructor injection



public class MyClassService {

private final MyClassRepo myClassRepo;

public DeviceServiceImpl(final MyClassRepo myClassRepo) {
this.myClassRepo = myClassRepo;
}

public boolean myMethodToTest() {
... whatever...
}
}


To test it: (Here comes my issue)



SpringRunner class OPTION 1: Constructor injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester (final MyClassRepository deviceRepository) {
this.myClassRepository = myClassRepository;
this.myClassService= new myClassService(myClassRepository);
}

}


Does not work since console output says:




Test class should have exactly one public zero-argument constructor




SpringRunner class OPTION 2: Autowired injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
@Autowired
private MyClassRepository myClassRepository;

private MyClassService myClassService = new myClassService(myClassRepository);

}



I feel like it is breaking the desired pattern.




SpringRunner class OPTION 3: Empty Constructor



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {

private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester () {
this.myClassRepository = new MyClassRepository(); // Obviously NOT working, since its an interface
this.myClassService= new myClassService(myClassRepository);
}
}



As commented: Obviously NOT working, since MyClassRepository its an interface




Is there any better approach to solve this issue?










share|improve this question























  • You could use Junit5. It allows constructors with multiple arguments.

    – pcoates
    Nov 22 '18 at 9:58











  • I don't think that the dependency injection by constructor pattern matters for tests.You're writing tests to test the functionality and the ability to do this comes first before the design patterns and so on. I don't think that any known pattern was meant for testing really. In the integration tests the context is killed when the tests are finished, so in my opinion @Autowired is the best and easiest way which I normally follow. It's not affecting your app in a bad way. But you should avoid that in the application code though.

    – Kamil Kozlowski
    Nov 22 '18 at 11:28
















0












0








0








I am trying to use Constructor Injection dependency pattern.



I wonder what is the correct approach to inject JPA Repositories on Integration test classes:



I have my source code:



RepoClass



@Repository
public interface MyClassRepo extends JpaRepository<MyClass, Long> {
... methods ...
}


Service following cosntructor injection



public class MyClassService {

private final MyClassRepo myClassRepo;

public DeviceServiceImpl(final MyClassRepo myClassRepo) {
this.myClassRepo = myClassRepo;
}

public boolean myMethodToTest() {
... whatever...
}
}


To test it: (Here comes my issue)



SpringRunner class OPTION 1: Constructor injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester (final MyClassRepository deviceRepository) {
this.myClassRepository = myClassRepository;
this.myClassService= new myClassService(myClassRepository);
}

}


Does not work since console output says:




Test class should have exactly one public zero-argument constructor




SpringRunner class OPTION 2: Autowired injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
@Autowired
private MyClassRepository myClassRepository;

private MyClassService myClassService = new myClassService(myClassRepository);

}



I feel like it is breaking the desired pattern.




SpringRunner class OPTION 3: Empty Constructor



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {

private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester () {
this.myClassRepository = new MyClassRepository(); // Obviously NOT working, since its an interface
this.myClassService= new myClassService(myClassRepository);
}
}



As commented: Obviously NOT working, since MyClassRepository its an interface




Is there any better approach to solve this issue?










share|improve this question














I am trying to use Constructor Injection dependency pattern.



I wonder what is the correct approach to inject JPA Repositories on Integration test classes:



I have my source code:



RepoClass



@Repository
public interface MyClassRepo extends JpaRepository<MyClass, Long> {
... methods ...
}


Service following cosntructor injection



public class MyClassService {

private final MyClassRepo myClassRepo;

public DeviceServiceImpl(final MyClassRepo myClassRepo) {
this.myClassRepo = myClassRepo;
}

public boolean myMethodToTest() {
... whatever...
}
}


To test it: (Here comes my issue)



SpringRunner class OPTION 1: Constructor injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester (final MyClassRepository deviceRepository) {
this.myClassRepository = myClassRepository;
this.myClassService= new myClassService(myClassRepository);
}

}


Does not work since console output says:




Test class should have exactly one public zero-argument constructor




SpringRunner class OPTION 2: Autowired injection



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {
@Autowired
private MyClassRepository myClassRepository;

private MyClassService myClassService = new myClassService(myClassRepository);

}



I feel like it is breaking the desired pattern.




SpringRunner class OPTION 3: Empty Constructor



@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfigClass.class) // With necessary imports
@SpringBootTest
public class MyClassTester {

private final MyClassService myClassService;
private final MyClassRepository myClassRepository;

public MyClassTester () {
this.myClassRepository = new MyClassRepository(); // Obviously NOT working, since its an interface
this.myClassService= new myClassService(myClassRepository);
}
}



As commented: Obviously NOT working, since MyClassRepository its an interface




Is there any better approach to solve this issue?







java spring spring-boot spring-test spring-boot-test






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 22 '18 at 9:45









MaydayMayday

1,6271827




1,6271827













  • You could use Junit5. It allows constructors with multiple arguments.

    – pcoates
    Nov 22 '18 at 9:58











  • I don't think that the dependency injection by constructor pattern matters for tests.You're writing tests to test the functionality and the ability to do this comes first before the design patterns and so on. I don't think that any known pattern was meant for testing really. In the integration tests the context is killed when the tests are finished, so in my opinion @Autowired is the best and easiest way which I normally follow. It's not affecting your app in a bad way. But you should avoid that in the application code though.

    – Kamil Kozlowski
    Nov 22 '18 at 11:28





















  • You could use Junit5. It allows constructors with multiple arguments.

    – pcoates
    Nov 22 '18 at 9:58











  • I don't think that the dependency injection by constructor pattern matters for tests.You're writing tests to test the functionality and the ability to do this comes first before the design patterns and so on. I don't think that any known pattern was meant for testing really. In the integration tests the context is killed when the tests are finished, so in my opinion @Autowired is the best and easiest way which I normally follow. It's not affecting your app in a bad way. But you should avoid that in the application code though.

    – Kamil Kozlowski
    Nov 22 '18 at 11:28



















You could use Junit5. It allows constructors with multiple arguments.

– pcoates
Nov 22 '18 at 9:58





You could use Junit5. It allows constructors with multiple arguments.

– pcoates
Nov 22 '18 at 9:58













I don't think that the dependency injection by constructor pattern matters for tests.You're writing tests to test the functionality and the ability to do this comes first before the design patterns and so on. I don't think that any known pattern was meant for testing really. In the integration tests the context is killed when the tests are finished, so in my opinion @Autowired is the best and easiest way which I normally follow. It's not affecting your app in a bad way. But you should avoid that in the application code though.

– Kamil Kozlowski
Nov 22 '18 at 11:28







I don't think that the dependency injection by constructor pattern matters for tests.You're writing tests to test the functionality and the ability to do this comes first before the design patterns and so on. I don't think that any known pattern was meant for testing really. In the integration tests the context is killed when the tests are finished, so in my opinion @Autowired is the best and easiest way which I normally follow. It's not affecting your app in a bad way. But you should avoid that in the application code though.

– Kamil Kozlowski
Nov 22 '18 at 11:28














1 Answer
1






active

oldest

votes


















0














Use Junit 5. It allows constructors with multiple arguments.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53428008%2fintegration-tests-on-springboot-with-constructor-injection-pattern%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Use Junit 5. It allows constructors with multiple arguments.






    share|improve this answer




























      0














      Use Junit 5. It allows constructors with multiple arguments.






      share|improve this answer


























        0












        0








        0







        Use Junit 5. It allows constructors with multiple arguments.






        share|improve this answer













        Use Junit 5. It allows constructors with multiple arguments.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 '18 at 11:30









        pcoatespcoates

        1,0551210




        1,0551210
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53428008%2fintegration-tests-on-springboot-with-constructor-injection-pattern%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to change which sound is reproduced for terminal bell?

            Can I use Tabulator js library in my java Spring + Thymeleaf project?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents