Unit tests with java - local object of daml ledger

I have application that interacts with daml ledger (I am using java bindings). Interaction mainly includes reading templates from ledger and exercising choices of templates. I am trying to write unit test without connecting to daml ledger and I want to statically create object of ledger. In other words, I want to compare static values of local daml ledger object and values that are returned from certain function in application which interact with real daml ledger.

Is there a way to create local java object of the ledger?

1 Like

@Tornike_Maridashvili Welcome to the forum!

Have you used the Daml assistant Java codegen capability?

I think for testing Daml business logic, using Daml scripts is a good approach. But for integrations against the ledger, the codegened representation gives you a faithful representation.

Even DA’s own tests that spin up a sandbox participant server within the same JVM as the tests do not inspect the participant’s in-memory representation directly; we always bind to a port and use the Ledger API to examine and set up Daml contracts and ledger state, even when the Sandbox and the tests are in the same JVM in this way.

So there are two good ways to go about this:

  1. Use the daml sandbox command in your fixtures to launch a sandbox.
  2. Examine the com.daml.platform.sandbox.fixture.SandboxFixture class in the digital-asset/daml open-source repo to learn how to use sandbox-on-x-app-lib as a library to launch a sandbox in the same image. (Again, please note that the users of SandboxFixture still interact with the sandbox solely via gRPC via the ledger client library; they do not look at the “local daml ledger object” directly.) This is not externally supported, nor a stable API; you will be on your own with this method.

By contrast, there is no way that I would recommend testing “without connecting to daml ledger”, so to speak. It is standard practice to spin up a sandbox just for running tests of the kind that you are talking about. daml sandbox doesn’t require a blockchain, or indeed any backing store whatsoever; it’s a good foundation for your application tests.

2 Likes

Can you clarify what do you mean by “object of ledger”? Do you mean:

  • an object representing some kind of stub or mock of a Ledger API server?
  • an object representing a generic Ledger API construct (e.g. a CreatedEvent)?
  • an object representing a Daml contract specific to the model you are using?

Perhaps if you could be more specific with regards with what you are testing we can be more helpful in replying to your question. Can you maybe share what types are you interacting with more precisely? Can you share an example of the signature of a function you’d like to test, or something relatively close to it?

1 Like

object of ledger I mean representing generic ledger api construct like CreatedEvent. I was able to represent created event, but I cannot represent DamlLedgerClient. Besides that I also need mock of ledger api server, because application changes contracts on daml ledger. For example, while exercising choice of contract it is archived and based on info of archived one new contract is created.

If you really need to mock a DamlLedgerClient, it implements the LedgerClient interface, which you can mock by either rolling your own mocks or using a mocking library. Note that you may want to restrict the scope of your mocking to what you actually need for testing (e.g. depending on the interaction you can probably just mock the CommandClient and TransactionClient, but of course that heavily depends on what you are testing).

With that said, it’s unclear to me why you’d want to mock a full server: mocking the client will be enough to ensure that you’re sending the calls you expect to be made. Any more mocking sounds like you’ll end up testing your mocks, instead of your logic. Once you use mocks to inspect calls and ensure that the interaction you have with the bindings are what you expect, based on what you are saying I would probably recommend doing integration tests with an actual ledger. The sandbox fully implements a Ledger API server and is a very good tool for these kind of tests.