Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 30, 2021 10:48 am GMT

First Mocked Unit Test Generated by DDTJ - Building DDTJ Day 9

Yesterday I ran into some snags, but I'm glad to report that this is all behind me. We finally have the first DDT generated test in history!

Id like to proclaim victory, but the road ahead is still long and the result is underwhelming at this point. We have generated code, but it still doesnt compile right away and at least for POJOs it doesnt inject the mocks (although it creates them). I think those are surmountable problems that we can solve moving forward.

But Im running a bit ahead. Lets talk about whats happening with the code right now Or at least in the current PR thats still waiting for more test coverage.

Right now Im running a super trivial application:

public class BasicApp {   private BasicDependency dependency = new BasicDependency();   public static void main(String[] args) throws InterruptedException {       new BasicApp().run();   }   public void run() throws InterruptedException {       System.out.println("This is the first testable method");       System.out.println(dependency.otherMethod("This prints three", 3));   }}

Which invokes:

public class BasicDependency {   public String otherMethod(String key, int counter) throws InterruptedException {       System.out.println("otherMethod");       return key + " " + counter;   }}

To generate a test for this, I used the following process:

Run the Backend Server

The server process collects the execution data from the app:

java -jar target/Backend-0.0.5-SNAPSHOT.jar

Run the App

The next stage is getting the server to run/debug the application. This replaces the standard java command line with something like this:

java -jar target/CLI-0.0.5-SNAPSHOT-shaded.jar -run dev.ddtj.backend.testdata.BasicApp -classpath Backend/target/test-classes

Notice this command is asynchronous since it runs in the backend server context.

Find and Generate the Test

First, we need to list the classes on which we have instrumentation:

java -jar target/CLI-0.0.5-SNAPSHOT-shaded.jar -c

Which prints out:

Class Name                                                  | Method Count    | Execution Count----------                                                  | ------------    | ---------------dev.ddtj.backend.testdata.BasicDependency                   | 1               | 1dev.ddtj.backend.testdata.BasicApp                          | 2               | 2

Next, we need to see the methods we can test in a specific class:

java -jar target/CLI-0.0.5-SNAPSHOT-shaded.jar -m dev.ddtj.backend.testdata.BasicApp

Which prints out:

Method Name                                                 | Total Execution-----------                                                 | ---------------main([Ljava/lang/String;)V                                  | 1run()V                                                      | 1

Now we need to find the tests available. When we have one test, it seems redundant, but it makes sense when we have more:

java -jar target/CLI-0.0.5-SNAPSHOT-shaded.jar -t "dev.ddtj.backend.testdata.BasicApp.run()V"

Prints out:

Test ID                                 | Test Hour of the Day-------                                 | --------------------JuZlJX5ERAKXZQR8CpYgiA--7               | Thu Dec 30 08:31:25 IST 2021

We can now generate a test based on these results:

java -jar target/CLI-0.0.5-SNAPSHOT-shaded.jar -g "dev.ddtj.backend.testdata.BasicApp,run()V,JuZlJX5ERAKXZQR8CpYgiA--7"

Which prints out:

/** * Generated by <a href="https://github.com/ddtj/ddtj/">ddtj</a> */package dev.ddtj.backend.testdata.test;import org.junit.jupiter.api.Test;import org.junit.jupiter.api.extension.ExtendWith;import org.mockito.Mock;import org.mockito.Mockito;import org.mockito.junit.jupiter.MockitoExtension;import dev.ddtj.backend.testdata.BasicApp;import dev.ddtj.backend.testdata.BasicDependency;@ExtendWith(MockitoExtension.class)class BasicAppTests {    @Test    void runTest() {        BasicDependency BasicDependencyMock = Mockito.mock(BasicDependency.class);        Mockito.lenient().when(BasicDependencyMock.otherMethod("This prints three", 3)).thenReturn("This prints three 3");        BasicApp myObjectInstance =  new BasicApp();        myObjectInstance.run();    }}

What Isnt Working?

There are several problems in the code above. First, we dont detect checked exceptions, so this code wont compile.

As a short-term workaround, Im adding a throws Exception to the test method. This ensures it compiles properly and fails as expected.

The bigger problem is that the mock isnt properly bound. I expected this since I didnt write the code for that and also theres technically no way to bind that mock. I hope this will work more reasonably when testing on real world code.

The code doesnt use the @Mock or @InjectMocks annotations. I think thats something that I can improve on. Id like to have multiple styles of test generation to support various personal tastes.

Since the mock isnt invoked, the test would fail on that, but I added the `lenient() call as a short-term workaround so we can move forward.

Whats Working?

Im so pleased it generated the mock code correctly and implemented the mock.

Object creation and dependencies included a lot of hairy code, but its coming together now and I think the basis is very good.

Im very pleased with the data collection code and the basic architecture. Now the key challenge is fine tuning and scaling this so it works correctly for more real world workloads.

I think Ill go into greater details on this in my postmortem blog post next week. I think I need to give this some time to see how everything fits together.

Tomorrow

Right now I have two big challenges ahead of me:

  1. Merge the PR - this will be hard, especially testing all this code I wrote
  2. Scale and improve to use cases

At this stage, Im pretty happy that I accomplished the basic goal. But I want to build a proper MVP so I hope I can get a real world application running. I think blue sky initiatives like a web interface, would have to wait until after this stage.

If you want to keep up with the latest updates on this series and the many other things I work on, then follow me on twitter.


Original Link: https://dev.to/codenameone/first-mocked-unit-test-generated-by-ddtj-building-ddtj-day-9-36lo

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To