How to mock 2 or multiple prepared statements per connection in jMock? - jmock

public void testCreate() throws ApplicationException {
DutyDrawback drawback = new DutyDrawback();
drawback.setSerialNumber("TEST123");
drawback.setSnProcessInd("Y");
drawback.setMediaNumber("TEST111");
drawback.setMnProcessInd("Y");
drawback.setConfirmedInd("Y");
drawback.setResponseCode("1");
drawback.setResponseMsg("MSG");
drawback.setLastChangedUser("USER");
drawback.setLastChangedDate(new Date(System.currentTimeMillis()));
mockILogger.expects(atLeastOnce()).method("informationalEvent");
Logger.setMockLogger((ILogger) mockILogger.proxy());
// Set up the statement expectations
Mock mockStatement = mock(PreparedStatement.class);
mockStatement.expects(atLeastOnce()).method("setString");
mockStatement.expects(once()).method("executeUpdate").will(returnValue(1));
Mock mockStatement1 = mock(PreparedStatement.class);
mockStatement1.expects(atLeastOnce()).method("setString");
mockStatement1.expects(once()).method("executeUpdate").will(returnValue(1));
// Set up the connection expectations
mockConnection.expects(once()).method("setAutoCommit");
mockConnection.expects(once()).method("commit");
mockConnection.expects(once()).method("prepareStatement").will(returnValue(mockStatement1.proxy()));
mockConnection.expects(once()).method("prepareStatement").will(returnValue(mockStatement.proxy()));
TVSUtils.setMockConnection((Connection) mockConnection.proxy());
DutyDrawbackDAO drawbackDAO = new DutyDrawbackDAO();
int count = drawbackDAO.create(drawback);
assertEquals(2, count);
}
I am getting the following trace:
org.jmock.core.DynamicMockError: mockPreparedStatement: unexpected invocation
Invoked: mockPreparedStatement.executeUpdate()
Allowed:
expected at least once and has been invoked: setString, is void
expected once and has been invoked: executeUpdate, returns <1>
at org.jmock.core.AbstractDynamicMock.mockInvocation(AbstractDynamicMock.java:96)
at org.jmock.core.CoreMock.invoke(CoreMock.java:39)
at $Proxy2.executeUpdate(Unknown Source)
at com.cat.tvs.dao.DutyDrawbackDAO.create(DutyDrawbackDAO.java:102)
at com.cat.tvs.dao.DutyDrawbackDAOTest.testCreate(DutyDrawbackDAOTest.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:58)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:60)
at java.lang.reflect.Method.invoke(Method.java:391)
at junit.framework.TestCase.runTest(TestCase.java:164)
at org.jmock.core.VerifyingTestCase.runBare(VerifyingTestCase.java:39)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
I am not sure what am I doing wrong here?
Thanks.

Firstly, you seem to be using jmock1, you might consider moving to jmock2.
The failure says that you're calling executeUpdate() when it's not expected. Are you calling it more than once?
Finally, I usually recommend not writing mock tests against JDBC, even though I wrote a paper many years ago showing how to do it. We talk about "only mock types you own" for a number of reasons, one of which is that mock tests assume that the third party implementation doesn't change. For JDBC, I'd recommend writing integration tests that run against a small instance of the real database.

Related

So, a mutant escaped. Now what?

I've just managed to get mutation testing working for the first time. My usual testing framework is Codeception but as of writing, it is not compatible with mutation testing (although I believe work is being done on it and it's not far off). I'm using PHPUnit and Infection, neither of which seem easy to work out how to use.
My test suite generated ten mutants. Nine were killed and one escaped. However, I don't know what part of the code or the tests needs to be improved to kill the final mutant.
How do you get information about what code allowed the mutant to escape?
I found in this blog what I couldn't find in Infection's documentation: the results are saved in infection.log.
The log file looks like this:
Escaped mutants:
================
1) <full-path-to-source-file>.php:7 [M] ProtectedVisibility
--- Original
+++ New
## ##
use stdClass;
trait HiddenValue
{
- protected function hidden_value($name = null, $value = null)
+ private function hidden_value($name = null, $value = null)
{
static $data = [];
$keys = array_map(function ($item) {
Timed Out mutants:
==================
Not Covered mutants:
====================
It says that the mutation changed the protected visibility to private and that no tests failed as a result. If this is important, I can now either change the code or write another test to cover this case.
Now that I've found this, I've searched on the Infection website for infection.log and found --show-mutations or -s which will output escaped mutants to the console while running.

How to trace references in an asynchronous IO code in WinDBG?

I have the addresses of two SqlConnection objects and wish to understand who holds a reference to them.
Object 1
0:042> !mroot 000000b97fd45868
AppDomain 000000bdeb50b7a0: GCHandle(Pinned) # 000000bdebc61bf8
000000bd7796f6d8[System.Object[]]
000000b97fd46308[a8iDynamixV30.BL.GlobalSetting]
000000b97fd45b18[a8i.a8iDatabaseConnection]
000000b97fd45868[System.Data.SqlClient.SqlConnection]
Object 2
0:042> !mroot 000000b99a5b0cf0
CLR Thread 0x57 # R14
000000bb92887ac8[System.Threading.Tasks.ContinuationTaskFromTask]
000000bb928d8048[System.Threading.Tasks.StandardTaskContinuation]
000000bb928d7ff8[System.Threading.Tasks.ContinuationTaskFromTask]
000000b9996a5ff0[System.Threading.Tasks.StandardTaskContinuation]
000000b9996a5fa0[System.Threading.Tasks.ContinuationTaskFromTask]
000000b9996a92a8[System.Threading.Tasks.StandardTaskContinuation]
000000b9996a9258[System.Threading.Tasks.ContinuationTaskFromTask]
000000bb928f0dc8[System.Threading.Tasks.StandardTaskContinuation]
000000bb928f0d78[System.Threading.Tasks.ContinuationTaskFromTask]
000000ba8ea86a18[System.Threading.Tasks.StandardTaskContinuation]
000000ba8ea869c8[System.Threading.Tasks.ContinuationTaskFromTask]
000000bb929084f8[System.Threading.Tasks.StandardTaskContinuation]
000000bb929084a8[System.Threading.Tasks.ContinuationTaskFromTask]
000000bb9291c4f8[System.Threading.Tasks.StandardTaskContinuation]
000000bb9291c4a8[System.Threading.Tasks.ContinuationTaskFromTask]
000000ba8eaa5dc8[System.Threading.Tasks.StandardTaskContinuation]
000000ba8eaa5c78[System.Threading.Tasks.ContinuationTaskFromTask]
000000bc99588ce8[System.Threading.Tasks.StandardTaskContinuation]
000000bc99588c98[System.Threading.Tasks.ContinuationTaskFromTask]
000000ba8eaddd60[System.Threading.Tasks.StandardTaskContinuation]
000000ba8eaddc10[System.Threading.Tasks.ContinuationTaskFromTask]
000000bc9c734110[System.Threading.Tasks.StandardTaskContinuation]
000000bc9c7340c0[System.Threading.Tasks.ContinuationTaskFromTask]
000000bc9c735330[System.Threading.Tasks.StandardTaskContinuation]
000000bc9c7351e0[System.Threading.Tasks.ContinuationTaskFromTask]
000000ba8eb1d158[System.Threading.Tasks.StandardTaskContinuation]
000000ba8eb1d108[System.Threading.Tasks.ContinuationTaskFromTask]
000000b999769f38[System.Threading.Tasks.StandardTaskContinuation]
000000b999769de8[System.Threading.Tasks.ContinuationTaskFromTask]
000000bb9298df28[System.Threading.Tasks.StandardTaskContinuation]
000000bb9298ded8[System.Threading.Tasks.ContinuationTaskFromTask]
000000b99a5c5980[System.Threading.Tasks.StandardTaskContinuation]
000000b99a5c5930[System.Threading.Tasks.ContinuationTaskFromTask]
000000b99a5c58f0[System.Action`1[[System.Threading.Tasks.Task, mscorlib]]]
000000b99a5c58d0[System.Web.Util.SynchronizationHelper+c__DisplayClass22_0]
000000b99a5c5890[System.Action]
000000b99a5c5870[System.Web.AspNetSynchronizationContext+c__DisplayClass22_0]
000000b99a5be490[System.Action]
000000b99a5be470[System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner]
000000b99a5bed30[SharpTop.Common.Utils.SqlUtil+d__1e`1[[System.Int32, mscorlib]]]
000000b99a5b0cf0[System.Data.SqlClient.SqlConnection]
I can pretty much understand what is going on with the Object 1, yet I am totally confused about the Object 2. I understand that the Object 2 is part of an async I/O, but is it at all possible to trace it back to the owner?
If not, can the code be written in a way that while being asynchronous it is also friendly to postmortem debugging?

Getting a strange bug in jxBrowser

So this is a strange one. My code does a bunch a things that are hard to explain (but if necessary I´ll try to explain), but the following works:
var res = data.delete_if (function(key, value) { return key == "a"; })
but the following crashes:
data.delete_if (function(key, value) { return key == "a"; })
So, the fact that I do not save the result of the delete_if function crashes the browser with the following stack trace:
Error: test: B environment should proxy a Ruby hash. (MDArraySolTest): Java::JavaLang::IllegalStateException: Channel stream was closed before response has been received.
java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498) org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:453)
Any ideas of why this happens? Any solutions? I can provide more information if needed.
EDIT1:
Doing some more tests I found out that the error occurs only if the call to data.delete_if is the last statement on the script. If I add for example: console.log(""); after the call, everything works fine.
Thanks

restubbing method in OCMock does not seem to work?

I am confused why this doesn't work...
[[[myObject stub] andReturnValue:#YES] isBadical];
NSLog(#"================> result: %i", [myObject isBadical]);
[[[myObject stub] andReturnValue:#NO] isBadical];
NSLog(#"================> new result: %i", [myObject isBadical]);
Result is:
2013-10-13 20:24:49.156 myApp[43197:c07] ================> result: 1
2013-10-13 20:24:49.157 myApp[43197:c07] ================> new result: 1
Is there a way to update the stubbed value without having to stop mocking and/or create a new mock object?
Use expect instead of stub. AFAIK it's not possible to stub a method twice with OCMock. You don't need to send verify after executing the code you want to test since you are not interested in verifying any expectations.

Flex3 / Air 2: NativeProcess doesn't accepts standard input data (Error #2044 & #3218)

I'm trying to open cmd.exe on a new process and pass some code to programatically eject a device; but when trying to do this all I get is:
"Error #2044: Unhandled IOErrorEvent:. text=Error #3218: Error while writing data to NativeProcess.standardInput."
Here's my code:
private var NP:NativeProcess = new NativeProcess();
private function EjectDevice():void
{
var RunDLL:File = new File("C:\\Windows\\System32\\cmd.exe");
var NPI:NativeProcessStartupInfo = new NativeProcessStartupInfo();
NPI.executable = RunDLL;
NP.start(NPI);
NP.addEventListener(Event.STANDARD_OUTPUT_CLOSE, CatchOutput, false, 0, true);
NP.standardInput.writeUTFBytes("start C:\\Windows\\System32\\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll");
NP.closeInput();
}
I also tried with writeUTF instead of writeUTFBytes, but I still get the error. Does anyone have an idea of what I'm doing wrong?.
Thanks for your time :)
Edward.
Maybe cmd.exe doesn't handle standardInput like a normal process.
You could try passing what you want to execute as parameters to the cmd process, rather than writing to the standard input
I think
cmd.exe /C "start C:\Windows\System32\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll"
is the format to pass something as a parameter to cmd to execute immediately.
This site has an example of passing process parameters using a string vector:
http://blogs.adobe.com/cantrell/archives/2009/11/demo_of_nativeprocess_apis.html
Try it without the last line "NP.closeInput();"
See also:
http://help.adobe.com/en_US/as3/dev/WSb2ba3b1aad8a27b060d22f991220f00ad8a-8000.html
I agree with abudaan, you shouldn't need to closeInput().
Also, suggest you add a line break at the end of the writeUTFBytes() call, e.g.:
NP.standardInput.writeUTFBytes("start C:\\Windows\\System32\\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll **\n**");
Lastly, I recommend you listen to other events on the NativeProcess, I use a block of code something like this:
NP.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStdOutData);
NP.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onStdErrData);
NP.addEventListener(Event.STANDARD_OUTPUT_CLOSE, onStdOutClose);
NP.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, onStdInputProgress);
NP.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOError);
NP.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR, onIOError);
NP.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
with the normal event handler functions that at least trace what they receive.
Best of luck - I've just spent a few hours refining NativeProcess with cmd.exe - its fiddly. But I got there in the end and you will too.

Resources