I am trying to test my gwt app with gwt junit but seems to not be able to set up things correctly to make the objectify be tested.
All the tutorials demonstrate testing DataStore but not objectify (which is higher level of data base service)
My base class for testing looks like this:
public class TestBase {
private static final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
protected static ObjectifyFactory fact;
#BeforeClass
public static void setUp() {
helper.setUp();
fact = new ObjectifyFactory() {
#Override
public Objectify begin(ObjectifyOpts opts)
{
opts.setSessionCache(false);
return super.begin(opts);
}
};
}
#AfterClass
public static void tearDown() {
helper.tearDown();
}
}
then i have classes that extends the base:
public class UserServiceTest extends TestBase{
private User inactiveUser;
private UserService us;
Objectify _ofy;
#Rule
public ExpectedException thrown = ExpectedException.none();
#Before
public void beforeTest() {
//Register the classes used in the test
fact.register(User.class);
us = new UserService();
inactiveUser = new User();
}
#Test
public void basicTest(){
Objectify ofy = ObjectifyService.begin();
ofy.put(inactiveUser); //This fails with exception: An exception occurred: com.google.apphosting.api.ApiProxy$CallNotFoundException
//My goal is to reach these test but "addUser" uses also objectify
//UserService.addUser("shpungin#gmail.com", "bye");
//assertNotNull(inactiveUser.get_id());
}
Do you have an idea of what am I doing wrong? I looked all over the Internet and found no solution (some even said to remove app-engine-sdk from .classpath but it dosent seems to work.
Thank you.
I solved this.
Although com.google.apphosting.api.ApiProxy should be part of the app-engine
Some jars still needs to be inside the .classpath :
${SDK_ROOT}/lib/testing/appengine-testing.jar
${SDK_ROOT}/lib/impl/appengine-api.jar
${SDK_ROOT}/lib/impl/appengine-api-labs.jar
${SDK_ROOT}/lib/impl/appengine-api-stubs.jar //This one I missed
Also I upgraded my app-engine to v 1.6.4.1 (maybe that also helped).
Related
I have a spring-boot application which calls some third party URL (let's say http://example.com/someUri) using webclient(I have used application-dev.properties for injecting this url in my application to achieve loose coupling) and consumes the response and use it in my application.
It's my first time when I am going to write test cases for webclient. and there I used #SprintBootTest.
I found that there are two ways where I can test my webclient with third party Api call by mocking the api call and make it call to my local url(which will be using url(http://localhost:{portNumber}/someUri) from my testing properties file: src/test/resources/application.properties) where It will be giving some mockedResponse in return to my real client:
Using wiremock
Using MockWebServer
consider above code for better understanding:
#Service
Class SampleService{
#Value("${sample.url}")
private String sampleUrl;
public String dummyClient() {
String sample =webClient.get()
.uri(sampleUrl)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.retrieve()
.bodyToMono(String.class)
.block();
return sample;
}
}
application-dev.properties:
sample.url:http://example.com/someUri
src/test/resouces/application.properties:
http://localhost:8090/someUri
Testing class:
#SpringBootTest
public class sampleTestingClass {
#Autowired
private SampleService sampleService;
#Value("${sample.url}")
private String sampleUrl;
public static MockWebServer mockWebServer = new MockWebServer();
#BeforeAll
static void setUp() throws IOException {
mockWebServer.start(8090);
}
#AfterAll
static void tearUp() throws IOException {
mockWebServer.close();
}
HttpUrl url = mockWebServer.url("/someUri");
mockWebServer
.enqueue(
new MockResponse()
.setResponseCode(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody("Sample Successful"));
String sample = sampleService.dummyClient();
assertEquals(sample ,matches("Sample Successful"));
}
}
but this code isn't working. it's giving me above error:
java.lang.NullPointerException
It will be really helpful if anybody knows how this can be fixed to achieve my unit testing using mocked Url? Thanks in advance!
Here is a working example:
#Component
public class QuotesClient {
private final WebClient webClient;
public QuotesClient(WebClient.Builder builder, #Value("${client.baseUrl}") String baseUrl) {
this.webClient = builder.baseUrl(baseUrl).build();
}
public JsonNode getData() {
return this.webClient
.get()
.retrieve()
.bodyToMono(JsonNode.class)
.block();
}
}
Using the WebClient.Builder is optional.
The corresponding test can look like the following:
class QuotesClientTest {
private QuotesClient quotesClient;
private MockWebServer server;
#BeforeEach
public void setup() {
this.server = new MockWebServer();
this.quotesClient = new QuotesClient(WebClient.builder(), server.url("/").toString());
}
#Test
public void test() {
server.enqueue(new MockResponse()
.setStatus("HTTP/1.1 200")
.setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}")
.addHeader("Content-Type", "application/json"));
JsonNode data = quotesClient.getData();
assertNotNull(data);
System.out.println(data);
}
}
If you are searching for a similar setup using WireMock, Spring Boot, and JUnit 5, take a look at the linked guide.
public class DummyTest {
#InjectMocks
private TestService service;
#Mock
private TestRepository repository;
#BeforeEach
public void before() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testMe() {
when(repository.findAllByQuery("")).thenReturn(List.of());
List<String> entities = service.findAllByQuery("test");
verify(repository, times(1)).findAllByQuery(anyString());
}
}
class TestService {
private TestRepository repository;
public List<String> findAllByQuery(String query) {
return repository.findAllByQuery(query);
}
}
class TestRepository {
public List<String> findAllByQuery(String query) {
return List.of("");
}
}
The test above successfully passed when I do Mockito initialization via #BeforeEach annotation.
After, I tried to remove #BeforeEach annotation and initialize Mockito with #ExtendWith(MockitoExtension.class) and the test failed due to:
org.mockito.exceptions.misusing.UnnecessaryStubbingException:
org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at DummyTest.testMe(DummyTest.java:33)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.
Could you please explain to me, why I got so different test execution results? Technically, I have just changed the way to initialize Mockito and that all.
#ExtendWith(MockitoExtension.class) and MockitoAnnotations.initMocks(this) configures Mockito in a little different way.
When you use #ExtendWith(MockitoExtension.class) additionally configures "strictness" of Mockito with default value STRICT_STUBS.
Which means you have to change the configuration of you stubs like this:
#Test
public void testMe() {
when(repository.findAllByQuery(anyString())).thenReturn(List.of());
List<String> entities = service.findAllByQuery("test");
verify(repository, times(1)).findAllByQuery(anyString());
}
or even like this:
#Test
public void testMe() {
when(repository.findAllByQuery(eq("test"))).thenReturn(List.of());
List<String> entities = service.findAllByQuery("test");
verify(repository, times(1)).findAllByQuery(anyString());
}
I have a class which I cannot easily use a dependency injection to mock due to an obligatory implementation of an interface - in a nutshell, for that reason I will be using Whitebox and my concern here is not related to the design, instead it is just to figure out how to properly "tearDown" the behavior caused by Whitebox. Bear with me for a second, I will give you more details - this is the main dummy class:
public class Dummy implements MandatoryInterface {
private static final Logger logger = Logger.getLogger(MethodHandles.lookup().lookupClass());
private final ObjectMapper mapper = new ObjectMapper();
#Override
public Object convertArgumentToJson(Object arg) {
if (arg != null) {
try {
return mapper.writeValueAsString(arg);
} catch (IOException e) {
// doSomething();
logger.error("Error tracking request", e);
}
}
return null;
}
}
Supposing that I want to cover what happens if an exception occurs here, the only way that I see is to use a Whitebox.setInternalState. Here the test:
public class DummyTest {
private Dummy dummy = new Dummy();
#Test
public void testA() throws IOException {
final ObjectMapper mock = Mockito.mock(ObjectMapper.class);
Whitebox.setInternalState(dummy, "mapper", mock);
Mockito.when(mock.writeValueAsString(Mockito.any()))
.thenThrow(new IOException());
Assert.assertNull(dummy.convertArgumentToJson("testA"));
}
#Test
public void testB() {
Assert.assertNotNull(dummy.convertArgumentToJson("testB"));
}
}
As you can see, I cannot define the mapper within the Dummy class as static, because of the Whitebox (it wouldn't work).
Having said that, after the execution of testA() we have the mapper being mocked:
The problem is: when executing the testB I don't want mock anymore - it should be the old instanced ObjectMapper initially included in Dummy. But what appears:
Now, my question:
What is the proper way to undo the
Whitebox.setInternalState(dummy, "mapper", mock);
P.S.: I have considered using a tearDown() like this:
#AfterMethod
public void tearDown(){
Whitebox.setInternalState(dummy, "mapper", originalState);
}
However, in this scenario, my pitest (mutation test) would consider that I'm not covering the initialization of ObjectMapper, so: is there a way just to undo the Whitebox for the rest of the tests without setting manually the old one?
Sorry for the long description and thanks in advance.
Regards,
Sorry guys, I managed to have it.
Just in case someone else could face the same question, the answer was easier than I supposed.
private static final String MAPPER_DESC = "mapper";
private ObjectMapper originalMapper;
#BeforeMethod
public void init() {
MockitoAnnotations.initMocks(this);
originalMapper = (ObjectMapper) Whitebox.getInternalState(converter, MAPPER_DESC);
}
#AfterMethod
public void tearDown() {
Whitebox.setInternalState(converter, MAPPER_DESC, originalMapper);
}
Then testA and testB can keep the same code. And the mutation test will still have the ObjectMapper attribute declaration covered as shown in the image:
I have the following four classes: DataConsumer, DataProducer, SomeQualifier, a META-INF/beans.xml and a test. The class files are coded as follows:
public class DataConsumer {
private boolean loaded = false;
#Inject
#SomeQualifier
private String someString;
public void afterBeanDiscovery(
#Observes final AfterBeanDiscovery afterBeanDiscovery,
final BeanManager manager) {
loaded = true;
}
public boolean getLoaded() {
return loaded;
}
public String sayHello() {
return someString;
}
}
public class DataProducer {
#Produces
#SomeQualifier
private final String sample = "sample";
}
public #interface SomeQualifier {
}
The unit test looks like this.
public class WeldTest {
#Test
public void testHelloWorld() {
final WeldContainer weld = new Weld().initialize();
final DataConsumer consumer = weld.instance()
.select(DataConsumer.class).get();
Assert.assertEquals("sample", consumer.sayHello());
Assert.assertTrue(consumer.getLoaded());
}
}
However, it is failing on the assertTrue with getLoaded() it appears that the #Observes does not get fired.
Take a look at arquillian: www.arquillian.org. It'll take care of all of this for you.
I found a similar question that had answered my question
CDI - Observing Container Events
Although I am unable to use DataConsumer as both an Extension and a CDI managed bean. So it needs a third class just to be the Extension. However, because Extension have no access to managed beans since they are not created yet, I conclude that is no possible solution to use an #Observes AfterBeanDiscovery to modify the bean data. Even the BeanManager that gets passed in cannot find any of the beans.
I'm trying to test my Session Beans with JUnit, but I can't. I've tried a lot of method, but still get some exceptions.
Here is what I need:
I have a few Stateless Session Beans I need to test. Each has the same #PersistenceContext and uses an EntityManager
With my test cases I need to test their methods. For instance: if I add an user with username X and then I try to add another one with the same username, I want to catch an Exception.
Can someone provide a simple and short generic test example? I've already read many, but I always get an error (I get NullPointerException for the EntityManager when I call a method like: sessionBean.method() (which does, for instance, entityManager.find(...)), or I am not able to initialize the Context, or other PersistenceException).
You might be interested in one of the latest posts of Antonio Goncalves:
WYTIWYR : What You Test Is What You Run
It tells about testing EJB with EntityManager using:
Mockito,
Embedded EJB Container,
Arquillian.
I solved creating a Stateless Session Bean and injecting its Entity Manager to test classes. I post the code in case someone will need it:
#Stateless(name = "TestProxy")
#Remote({TestProxyRemote.class})
public class TestProxy implements TestProxyRemote {
#PersistenceContext(unitName = "mph")
private EntityManager em;
#Override
public void persist(Object o) {
em.persist(o);
}
#Override
public void clear() {
em.clear();
}
#Override
public void merge(Object o) {
em.merge(o);
}
#Override
#SuppressWarnings({ "rawtypes", "unchecked" })
public Object find(Class classe, String key) {
return em.find(classe, key);
}
#Override
#SuppressWarnings({ "rawtypes", "unchecked" })
public Object find(Class classe, long key) {
return em.find(classe, key);
}
#SuppressWarnings("rawtypes")
#Override
public List getEntityList(String query) {
Query q = em.createQuery(query);
return q.getResultList();
}
}
public class MyTest {
#BeforeClass
public static void setUpBeforeClass() throws NamingException {
Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.setProperty(Context.PROVIDER_URL, "localhost:1099");
env.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
jndiContext = new InitialContext(env);
try {
proxy = (TestProxyRemote) jndiContext.lookup("TestProxy/remote");
} catch (NamingException e) {
e.printStackTrace();
}
}
}
Then I can use proxy.find() to get the entities I need, o proxy.getEntityList() to execute a query to retrieve all the instance of an Entity. Or I can add other methods if I want.
Unitils provides a really cool support for JPA. Unitils can be used with JUnit or TestNG and in case you need a mocking framework, Unitils provides its own mocking module as well as support for EasyMock.
#JpaEntityManagerFactory(persistenceUnit = "testPersistenceUnit")
#DataSet(loadStrategy = RefreshLoadStrategy.class)
public class TimeTrackerTest extends UnitilsTestNG {
#TestedObject
private TimeTrackerBean cut = new TimeTrackerBean();
#InjectInto(target="cut",property="em")
#PersistenceContext
private EntityManager em;
#Test
#DataSet("TimeTrackerTest.testAddTimeSlot.xml")
public void yourTest() {
...
}
}
#JpaEntityManagerFactory - Used to specify your persistence unit. It automatically picks up the persistence.xml from your project classpath.
#DataSet - Just in case you need to load any test data you can use this.
#TestedObject - Marks your Class Under Test
#PersistenceContext - Automatically creates your EntityManager instance from the configurations made in the persistence.xml - PersistenceUnit.
#InjectInto - Injects the em instance into the target (cut)
For more information refer this.
Hope this helps.
I'm using Needle for this. It works well with Mockito and EasyMock if you want to mock other objects.
First I write a persistencte.xml for tests (src/test/resources/META-INF) like this:
<persistence-unit name="rapPersistenceTest" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/test"/>
...
</properties>
</persistence-unit>
In my Junit-Testclass I write:
public class DaoNeedleTest {
//here Needle will create persistenceContext for your testclass
public static DatabaseRule databaseRule = new DatabaseRule("rapPersistenceTest");
//here you can get the entityManager to manipulate data directly
private final EntityManager entityManager = databaseRule.getEntityManager();
#Rule
public NeedleRule needleRule = new NeedleRule(databaseRule);
//here you can instantiate your daoService
#ObjectUnderTest
DAOService daoService;
#Test
public void test() {
//if your method needs a transaction here you can get it
entityManager.getTransaction().begin();
daoService.yourMethod();
entityManager.getTransaction().commit();
}
You also need a Needle-configuration File in src/test/resources, where you tell what kind of Mock-provider you are using. E.g. I'm using Mockito:
mock.provider=de.akquinet.jbosscc.needle.mock.MockitoProvider
That's it.