how to apply in DebuggerHiddenAttribute dependent/cascade methods - unit-testing

I'm trying to ignore a exception that happen when run my test Methods.
I`m using a unitTest proyect.
The problem apears when
TestCleanup Method runs. It's a recursive method. This method clean all entities created in DB during the test. This is a recursive method because of dependences.
Anyway this method call to delete generic method in my ORM(Petapoco). It throws an exception if it can't delete the entity. Any problem, it run again with recursive way until delete it.
Now the problem, if i'm debugging VS stop a lot of times in Execute method because of failed deletes. But I can't modify this method to ignore it. I need a way to ignore this stops when i'm debugging tests. A way like DebuggerHiddenAttribute or similar.
Thanks!
I tried to use DebuggerHiddenAttribute, but cannot works in methods called by main method.
[TestCleanup(), DebuggerHidden]
public void CleanData()
{
ErrorDlt = new Dictionary<Guid, object>();
foreach (var entity in TestEntity.CreatedEnt)
{
try
{
CallingTest(entity);
}
catch (Exception e)
{
if (!ErrorDlt.ContainsKey(entity.Key))
ErrorDlt.Add(entity.Key, entity.Value);
}
}
if (ErrorDlt.Count > 0)
{
TestEntity.CreatedEnt = new Dictionary<Guid, object>();
ErrorDlt.ForEach(x => TestEntity.CreatedEnt.Add(x.Key, x.Value));
CleanData();
}
}
public int Execute(string sql, params object[] args)
{
try
{
OpenSharedConnection();
try
{
using (var cmd = CreateCommand(_sharedConnection, sql, args))
{
var retv = cmd.ExecuteNonQuery();
OnExecutedCommand(cmd);
return retv;
}
}
finally
{
CloseSharedConnection();
}
}
catch (Exception x)
{
OnException(x);
throw new DatabaseException(x.Message, LastSQL, LastArgs);
}
}
Error messages are not required.

Related

How can I prevent a method call when JUnit testing with Mockito?

For the life of me, I can't seem to figure out how to prevent the method I'm testing from calling a method in another class.
Here is my test class:
#ExtendWith(MockitoExtension.class)
class QueryHandlerTest {
#InjectMocks
QueryHandler queryHandler;
#Mock
ResponseBuilder responseBuilder;
#BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
#Test
void TC5() {
doThrow(AddMessageResponseException.class).when(responseBuilder).addMessageResponse(isA(Boolean.class), isA(Boolean.class));
assertThrows(AddMessageResponseException.class, ()-> queryHandler.addMessage("Hello",true));
}
}
Here is the method that I'm testing:
public void addMessage(String message, boolean lengthExceedsLimit) {
boolean messageAdded;
if (checkIfJarExists()) {
if (!lengthExceedsLimit) {
// attempt to add the message to the jar
messageAdded = addMessageQuery(new Message(event.getMessageAuthor().getIdAsString(), message));
} else {
messageAdded = false;
}
} else {
messageAdded = false;
}
responseBuilder.addMessageResponse(messageAdded, lengthExceedsLimit);
if (messageAdded) {
// check to see if the jar's message limit has been reached; if so, perform opening ceremony
if (checkMessageLimit()) {
responseBuilder.performOpeningEvent(currentJar);
deleteJarQuery(this.serverId);
}
}
}
And here is the method that it's calling:
public void addMessageResponse(boolean messageAdded, boolean lengthExceedsLimit){
if (lengthExceedsLimit) {
event.getChannel().sendMessage("I'm sorry, your message is too long. Please limit your message " +
"to 250 characters or less.");
} else if(messageAdded){
String nickname = getNickname();
event.getChannel().sendMessage("Thanks, " + nickname + "! Your message has " +
"been added to the jar!");
} else {
event.getChannel().sendMessage("Sorry, it looks like a jar has not been set up for your server. " +
"If you're a server admin, you can create a jar! " +
"Please use '!tiko help' to see a list of my commands.");
}
}
When I run the test, I get this output:
org.opentest4j.AssertionFailedError: Unexpected exception type thrown,
Expected :class com.tikoJar.exceptions.AddMessageResponseException
Actual :class java.lang.NullPointerException
<Click to see difference>
...
Caused by: java.lang.NullPointerException: Cannot invoke "org.javacord.api.entity.channel.TextChannel.sendMessage(String)" because the return value of "org.javacord.api.event.message.MessageCreateEvent.getChannel()" is null
at com.tikoJar.DTO.ResponseBuilder.addMessageResponse(ResponseBuilder.java:35)
at com.tikoJar.DTO.QueryHandler.addMessage(QueryHandler.java:74)
at com.tikoJar.DTO.QueryHandlerTest.lambda$TC5$0(QueryHandlerTest.java:68)
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:53)
... 73 more
As you can see, the method I'm testing is calling and running the addMessageResponse() method in the ResponseBuilder class, even though I specified in my test that a custom exception should be thrown when attempting to call that method.
I've also tried specifying:
doNothing().when(responseBuilder).addMessageResponse(isA(Boolean.class), isA(Boolean.class));
... but the method still gets called and run. What can I do here?

Unit testing suspend coroutine

a bit new to Kotlin and testing it... I am trying to test a dao object wrapper with using a suspend method which uses an awaitFirst() for an SQL return object. However, when I wrote the unit test for it, it is just stuck in a loop. And I would think it is due to the awaitFirst() is not in the same scope of the testing
Implementation:
suspend fun queryExecution(querySpec: DatabaseClient.GenericExecuteSpec): OrderDomain {
var result: Map<String, Any>?
try {
result = querySpec.fetch().first().awaitFirst()
} catch (e: Exception) {
if (e is DataAccessResourceFailureException)
throw CommunicationException(
"Cannot connect to " + DatabaseConstants.DB_NAME +
DatabaseConstants.ORDERS_TABLE + " when executing querySelect",
"querySelect",
e
)
throw InternalException("Encountered R2dbcException when executing SQL querySelect", e)
}
if (result == null)
throw ResourceNotFoundException("Resource not found in Aurora DB")
try {
return OrderDomain(result)
} catch (e: Exception) {
throw InternalException("Exception when parsing to OrderDomain entity", e)
} finally {
logger.info("querySelect;stage=end")
}
}
Unit Test:
#Test
fun `get by orderid id, null`() = runBlocking {
// Assign
Mockito.`when`(fetchSpecMock.first()).thenReturn(monoMapMock)
Mockito.`when`(monoMapMock.awaitFirst()).thenReturn(null)
// Act & Assert
val exception = assertThrows<ResourceNotFoundException> {
auroraClientWrapper.queryExecution(
databaseClient.sql("SELECT * FROM orderTable WHERE orderId=:1").bind("1", "123") orderId
)
}
assertEquals("Resource not found in Aurora DB", exception.message)
}
I noticed this issue on https://github.com/Kotlin/kotlinx.coroutines/issues/1204 but none of the work around has worked for me...
Using runBlocking within Unit Test just causes my tests to never complete. Using runBlockingTest explicitly throws an error saying "Job never completed"... Anyone has any idea? Any hack at this point?
Also I fairly understand the point of you should not be using suspend with a block because that kinda defeats the purposes of suspend since it is releasing the thread to continue later versus blocking forces the thread to wait for a result... But then how does this work?
private suspend fun queryExecution(querySpec: DatabaseClient.GenericExecuteSpec): Map {
var result: Map<String, Any>?
try {
result = withContext(Dispatchers.Default) {
querySpec.fetch().first().block()
}
return result
}
Does this mean withContext will utilize a new thread, and re-use the old thread elsewhere? Which then doesnt really optimize anything since I will still have one thread that is being blocked regardless of spawning a new context?
Found the solution.
The monoMapMock is a mock value from Mockito. Seems like the kotlinx-test coroutines can't intercept an async to return a mono. So I forced the method that I can mock, to return a real Mono value instead of a Mocked Mono. To do so, as suggested by Louis. I stop mocking it and return a real value
#Test
fun `get by orderid id, null`() = runBlocking {
// Assign
Mockito.`when`(fetchSpecMock.first()).thenReturn(Mono.empty())
Mockito.`when`(monoMapMock.awaitFirst()).thenReturn(null)
// Act & Assert
val exception = assertThrows<ResourceNotFoundException> {
auroraClientWrapper.queryExecution(
databaseClient.sql("SELECT * FROM orderTable WHERE orderId=:1").bind("1", "123") orderId
)
}
assertEquals("Resource not found in Aurora DB", exception.message)
}

Apache Beam: Why does it write to Spanner twice on REPORT_FAILURES mode?

I found interesting write operation codes while looking at SpannerIO, and want to understand reasons.
On write(WriteToSpannerFn) and REPORT_FAILURES failure mode, it seems trying to write failed mutations twice.
I think it's for logging each mutation's exceptions. Is it a correct assumption, and is there any workaround?
Below, I removed some lines for simplicity.
public void processElement(ProcessContext c) {
Iterable<MutationGroup> mutations = c.element();
boolean tryIndividual = false;
try {
Iterable<Mutation> batch = Iterables.concat(mutations);
spannerAccessor.getDatabaseClient().writeAtLeastOnce(batch);
} catch (SpannerException e) {
if (failureMode == FailureMode.REPORT_FAILURES) {
tryIndividual = true;
} else {
...
}
}
if (tryIndividual) {
for (MutationGroup mg : mutations) {
try {
spannerAccessor.getDatabaseClient().writeAtLeastOnce(mg);
} catch (SpannerException e) {
LOG.warn("Failed to submit the mutation group", e);
c.output(failedTag, mg);
}
}
}
}
So rather than write each Mutation individually to the database, the SpannerIO.write() connector tries to write a batch of Mutations in a single transaction for efficiency.
If just one of these Mutations in the batch fails, then the whole transaction fails, so in REPORT_FAILURES mode, the mutations are re-tried individually to find which Mutation(s) are the problematic ones...

PowerMock + EasyMock unexpected method call

I have a method like this which I want to unit test
public void update(String collectionName, BasicDBObject query, BasicDBObject updateObj){
try{
DBCollection collection = getCollection(collectionName);
collection.update(query, updateObj, true, false);
} catch (MongoException e) {
if (e.getMessage().startsWith("can't call something")) {
refreshConnection(collectionName);
} else {
throw e;
}
}
}
And the test code is as below. I have tried both the methods in the comments in unit test case and currently have commented it.
#Test
public void testUpdate(){
MongoStore store = PowerMock.createStrictPartialMockForAllMethodsExcept(MongoStore.class, "update");
DBCollection collection = PowerMock.createMock(DBCollection.class);
BasicDBObject updateobj = new BasicDBObject("test","shrikar");
String name = "testcoll";
String id = "123";
BasicDBObject query = new BasicDBObject("id",id);
EasyMock.expect(store.getCollection(name)).andReturn(collection);
//EasyMock.expect(collection.update(EasyMock.anyObject(BasicDBObject.class),EasyMock.anyObject(BasicDBObject.class),EasyMock.anyBoolean(),EasyMock.anyBoolean()));
//EasyMock.expect(collection.update(query,updateobj,true,false));
PowerMock.replayAll();
store.update(name,query,updateobj);
EasyMock.expectLastCall().times(1);
PowerMock.verifyAll();
}
In all the cases I keep getting
Unexpected Method call DBCollection.update({"id":"123"},{"test":"shrikar"}, true, false)
What am I missing?
Ok I found out the problem I had forgotten to add Mongo*.class to PrepareForTest
#PrepareForTest({MongoStore.class,MongoOptions.class,Mongo.class, BasicDBObject.class,DBCursor.class,DBObject.class})

J2ME Stub generates an unknown exception with JPA Entity types

I created a web service stub using NetBeans 7.0 and when I try using it, it throws an unknown Exception. I don't even know what part of my code to show here, all I know is that bolded line generates an unknown Exception:
public Businesses[] findBusiness(String query) throws java.rmi.RemoteException {
Object inputObject[] = new Object[]{
query
};
Operation op = Operation.newInstance(_qname_operation_findBusiness, _type_findBusiness, _type_findBusinessResponse);
_prepOperation(op);
op.setProperty(Operation.SOAPACTION_URI_PROPERTY, "");
Object resultObj;
try {
resultObj = op.invoke(inputObject);
} catch (JAXRPCException e) {
Throwable cause = e.getLinkedCause();
if (cause instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException) cause;
}
throw e;
}
return businesses_ArrayfromObject((Object[]) resultObj);
}
private static Businesses[] businesses_ArrayfromObject(Object obj[]) {
if (obj == null) {
return null;
}
Businesses result[] = new Businesses[obj.length];
for (int i = 0; i < obj.length; i++) {
result[i] = new Businesses();
Object[] oo = (Object[]) obj[i];
result[i].setAddress((String) oo[0]); // **exception here**
result[i].setEmail((String) oo[1]);
result[i].setId((Integer) oo[2]);
result[i].setName((String) oo[3]);
result[i].setPhoneno((String) oo[4]);
result[i].setProducts((String) oo[5]);
}
return result;
}`
I tried to consume the same webservice using a web application and it works quite well. I don't have a single clue to what is causing this exception. Any comment would be appreciated.
Update
I tried other services that return a String data type and it works fine. So I thought maybe J2ME has issues with JPA Entity types.
So my question is how do I return the data properly so that the J2ME client can read it well?