Is it possible to create spy(mock) object in testing class?
Here is tested class.
#Stateless
#Slf4j
public class UserDao {
#Inject
private TestBean testBean;
public String mock() {
return testBean.mock();
}
public String notMock() {
return testBean.notMock();
}
}
TestBean code
#Stateless
#Slf4j
public class TestBean {
public String notMock() {
return "NOT MOCK";
}
public String mock() {
return "IMPLEMENTED MOCK";
}
}
Here's my test
#RunWith(Arquillian.class)
public class UserDataTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
#Inject
private UserDao userDao;
#Deployment
protected static Archive createWar() {
File[] dependencies = Maven.configureResolver()
.withRemoteRepo("nexus-remote", "http://maven.wideup.net/nexus/content/groups/public/", "default")
.withRemoteRepo("nexus-release", "http://maven.wideup.net/nexus/content/repositories/releases/", "default")
.resolve(
"org.slf4j:slf4j-simple:1.7.7",
"eu.bitwalker:UserAgentUtils:1.15",
"org.mockito:mockito-all:1.10.8"
).withoutTransitivity().asFile();
return ShrinkWrap
.create(WebArchive.class, "pass.jpa.war")
.addAsWebInfResource("jbossas-ds.xml")
.addAsWebInfResource("jboss-deployment-structure.xml")
.addAsLibraries(
PassApiDeployments.createDefaultDeployment(),
PassUtilLibrary.createDefaultDeployment(),
PassJpaDeployments.createDefaultDeployment()
).addAsLibraries(dependencies);
}
#Test
public void testMock() {
assertEquals("MOCK", userDao.mock());
}
#Test
public void testNotMock() {
assertEquals("NOT MOCK", userDao.notMock());
}
}
I'd like to create a spy object on TestBean to change result on method test() of this bean.
So is it possible to create TestBean spy in UserDao.
I solve some problems through producer like this.
#Singleton
public class MockFactory {
#Produces
#ArquillianAlternative
public TestBean getTestBean() {
return when(mock(TestBean.class).mock()).thenReturn("MOCK").getMock();
}
}
But in this example I need create on Bean completely on my own. And if it is bean with additional dependencies and thus i will manage all dependencies.
As far as I know, its not possible to use a mocking framework in combination with arquillian ...
I haven't used it myself, but this Arquillian extension seems to be specifically designed to support Mockito Spy objects in an Arquillian test: https://github.com/topikachu/arquillian-extension-mockito/
Related
I am using spring boot WebFlux handler functions and route functions with mongodb. Below is my ReactiveMongoRepository interface and handler classes.
ReactiveMongoRepository interface
public interface UserReactiveMongoRepository extends ReactiveMongoRepository<User, String> {
Mono<User> findByEmail(#Param("email") String email);
Mono<User> findByUsername(#Param("username") String username);
Mono<User> findById(#Param("id") Long id);
Mono<Void> saveUser(Mono<User> monoUser);
}
UserHandler class
#Component
public class UserHandler {
private UserReactiveMongoRepository userRepository;
public UserHandler() { }
#Autowired
public UserHandler(#NonNull UserReactiveMongoRepository userRepository) {
this.userRepository = userRepository;
}
But userRepository instance is not generated on handler component class. I think this error seems to be simple, But I have no idea how. Any reply will be thankful.
I missed "spring-boot-starter-data-mongodb-reactive" dependency on pom.xml. So I added that dependency. And It works without errors.
Scenario
I've got a Spring Boot application with a #Configuration annotated Spring configuration class which contains some #Value annotated fields. For testing I want to replace these field values with custom test values.
Unfortunately these test values cannot be overridden using a simple properties file, (String) constants or similar, instead I must use some custom written property resolving Java class (e.g. TargetProperties.getProperty("some.username")).
The problem I have is that when I add a custom PropertySource to the ConfigurableEnvironment within my test configuration, it's already too late because this PropertySource will be added after the e.g. RestTemplate has been created.
Question
How can I override #Value annotated fields within a #Configuration class with properties obtained programmatically via custom Java code before anything else gets initialized?
Code
Production Configuration Class
#Configuration
public class SomeConfiguration {
#Value("${some.username}")
private String someUsername;
#Value("${some.password}")
private String somePassword;
#Bean
public RestTemplate someRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(
new BasicAuthorizationInterceptor(someUsername, somePassword));
return restTemplate;
}
}
Test Configuration Class
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class SomeTest {
#SpringBootConfiguration
#Import({MySpringBootApp.class, SomeConfiguration.class})
static class TestConfiguration {
#Autowired
private ConfigurableEnvironment configurableEnvironment;
// This doesn't work:
#Bean
#Lazy(false)
// I also tried a #PostConstruct method
public TargetPropertiesPropertySource targetPropertiesPropertySource() {
TargetPropertiesPropertySource customPropertySource =
new TargetPropertiesPropertySource();
configurableEnvironment.getPropertySources().addFirst(customPropertySource);
return customPropertySource;
}
}
}
You can override properties directly in the #SpringBootTest annotation using the properties parameter:
#SpringBootTest(properties = {"some.username=user", "some.password=pwd"},
webEnvironment = SpringBootTest.WebEnvironment.NONE)
You can use #TestPropertySource
#TestPropertySource(
properties = {
"some.username=validate",
"some.password=false"
}
)
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ApplicationTest {
//...
}
You can use constructor injection in production cases, which allows it to set the configuration manually:
#Configuration
public class SomeConfiguration {
private final String someUsername;
private final String somePassword;
#Autowired
public SomeConfiguration(#Value("${some.username}") String someUsername,
#Value("${some.password}") String somePassword) {
this.someUsername = someUsername;
this.somePassword = somePassword;
}
...
)
}
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class SomeTest {
private SomeConfiguration config;
#Before
public init() {
config = new SomeConfiguration("foo", "bar");
}
}
I'm trying to use arquillian to test one method of an EJB using a webservice through #WebServiceRef annotation
In my method decorated by #Deployment I declared the resource
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addPackages(true, .... PortType.class.getPackage())
.addAsResource("test-my.wsdl","my.wsdl")
.addAsManifestResource("META-INF/beans.xml", "beans.xml").addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
Then I coded the bean as following
#Stateless
#LocalBean
public class WSBean {
#WebServiceRef(wsdlLocation = "/my.wsdl")
PortType portType;
public void test() throws Exception{
portType.lireAdresseClient(null, null);
}
}
and the test
#RunWith(Arquillian.class)
public class WSintegrationTest extends DefaultServicesIntegrationTest {
#Deployment
....
#Inject
private WSBean wsBean;
#Test
public void testAppel() throws Exception {
System.out.println("TEST APPEL");
wsBean.test();
}
}
Can I do that with Arquillian ?
How can I fix it ?
Thanks
Regards
Also if you want you can take a look at https://github.com/javaee-samples/javaee7-samples/tree/master/jaxws you will find examples of JAXWS with its Arquillian test.
I have a properties file and I would like to inject a property in a service.
I would like use the constructor method for DI like this:
#Inject
public ScanService(#Named("stocks.codes") String codes, IYahooService yahooService) {
this.yahooService = yahooService;
this.codes = codes;
}
I try to do a module like specified in this link => Dagger: Inject #Named strings?
#Provides
#Named("stocks.code")
public String providesStocksCode() {
return "test";
}
And for the provider method for my service:
#Provides
#Singleton
public IScanService provideScanService(String codes, IYahooService yahooService){
return new ScanService(codes, yahooService);
}
When I run the compilation I get this error:
[ERROR]
/Users/stocks/src/main/java/net/modules/TestModule.java:[22,7]
error: No injectable members on java.lang.String. Do you want to add
an injectable constructor? required by
provideScanService(java.lang.String,net.IYahooService)
for net.modules.TestModule
How can I inject my property correctly in the constructor ?
Thanks.
You have two different names: stocks.codes and stocks.code.
You will also have to annotate your provideScanService codes parameter:
#Provides
#Singleton
public IScanService provideScanService(#Named("stocks.codes") String codes, IYahooService yahooService){
return new ScanService(codes, yahooService);
}
Or do it like this:
#Provides
#Singleton
public IScanService provideScanService(ScanService scanService){
return scanService;
}
If you mean Dagger 2, I can help you.
First you have to declare dependencies in Component
#Singleton
#Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
#Named("cloud") UserDataSource userCloudSource();
#Named("disc") UserDataSource userDiscSource();
UserDataRepository userDataRepository();
}
then instantiate it in Module
#Module
public class ApplicationModule {
#Provides #Named("cloud")
UserDataSource provideCloudUserSource(UserCloudSource userSource) {
return userSource;
}
#Provides #Named("disc")
UserDataSource provideDiscUserSource(UserDiscSource userSource) {
return userSource;
}
#Provides
UserDataRepository provideUserRepository(UserDataRepository repository) {
return repository;
}
}
then inject it in constructor with #Named qualifiers
#Inject
public UserDataRepository(#Named("cloud") UserDataSource cloudSource,
#Named("disc") UserDataSource discSource) {
this.cloudDataSource= cloudSource;
this.discDataSource = discSource;
}
I have the following classes:
The class to be injected with a dependency
public class ToBeInjected
{
[Inject]
public void InjectCommandParameters( IInjectParameters parameters )
{
// some set code here
}
}
The dependency to be injected that implements IInjectParameters
and an injector
public class Injector
{
public void SetParameters( ToBeInjected statement, IInjectParameters parameters )
{
statement.InjectCommandParameters(parameters);
}
}
so what I try to achieve statement.InjectCommandParameters(parameters) by using ninject.