0
votes

My purpose is to produce EntityManager and Logger SFL4J implementations for my cucumber guice unit tests.

I've created the following resource producer

public class MockResourcesWeb {

    private static final Logger logger = LoggerFactory.getLogger(MockResourcesWeb.class);

    private EntityManager entityManager;

    @PostConstruct
    void init() {
        try {
            entityManager = Persistence.createEntityManagerFactory("h2-test").createEntityManager();
        } catch (Exception e) {
            logger.warn("Failed to initialize persistence unit", e);
        }
    }

    @Produces
    public EntityManager getEntityManager(InjectionPoint injectionPoint) {
        return entityManager;
    }

    @Produces
    public Logger produceLog(InjectionPoint injectionPoint) {
        return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
    }

}

Now I guess I should bind those classes using my implementation of AbstractModule so: public class ServiceModule extends AbstractModule { @Override protected void configure() { bind( EntityManager.class ).to(?); // ... (further bindings) } }

I have no idea how to realize this. I've also tried by expliciting it:

bind( EntityManager.class ).to(Persistence.createEntityManagerFactory("h2-test").createEntityManager());

But it still fails to compile.

Any suggestions ?

1

1 Answers

1
votes

My purpose is to produce EntityManager and Logger SFL4J implementations for my cucumber guice unit tests.

To have instance of EntityManager and SFL4J using guice injection

you can use cucumber-guice as below

  <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-guice</artifactId>
            <version>6.4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>4.2.3</version>
            <scope>test</scope>
        </dependency>

Then in a Global class

import com.google.inject.Singleton;
import io.cucumber.guice.ScenarioScoped;

// Scenario scoped it is used to show Guice
// what will be the shared classes/variables and instantiate them only in here
@ScenarioScoped
//@Singleton
public class Global {
 
   public EntityManager  entityManager = new EntityManager();
}

Create a BasePage class and pass Global in constructor

//import classes   
public class BasePage {

    protected Global global;

    public BasePage(Global global) {
        this.global = global;
    }
}

Now in your stepdefinitions ( unit tests or other cucumber tests)

  import com.google.inject.Inject;
  //import other classes as necessary

public class StepDefs extends BasePage {
    
         public static EntityManager entityMgr; 
    
        @Inject
        public StepDefs(Global global) {
            super(global);
            StepDefs.entityMgr = global.entityManager
        }
     //use entityMgr as needed

     //note that a new instance of entityMgr will be created for each scenario in feature file`
     // to create an instance that will last for all tests use @singleton in Global class . ex : for sfl4j
  }