Heschoon
Heschoon

Reputation: 3019

Converting a mock to JSON in Spock

One of the objects I've mocked must be converted into JSON but Spock does not seem to support the mocking of convertions. How can I choose which JSON will be returned?

Example of what I would like to achieve:

def "convert as JSON"()
{
    when:
    def product = Mock(Product)
    println(product as JSON)
    then:
    1* (product as JSON) << (["message": "message"] as JSON)
}

This does not work however.

EDIT: Mocking the way the object is converted into JSON is useful, because what I want to achieve is to test a method of another class, that takes a product as argument and use it, calling "as JSON" on the product during it's execution. Since the products can be complex and have lots of dependencies and fields, I prefer to mock them. Spock then gives control over the output of the mocked products methods but it gets trickier when conversion is needed...

Upvotes: 0

Views: 872

Answers (1)

Aaron Digulla
Aaron Digulla

Reputation: 328644

In your test, you're trying to reduce the complexity of an object (Product) to make your tests more simple. This is dangerous for two reasons:

  1. Complicated tests are a code smell. They tell you "something is wrong". Trying to apply lots of deodorant on the smell will make things worse.
  2. You're testing scenarios which can't happen in production.

The clean/better solution would be to refactor Product until it can be created easily and you don't need to mock it anymore. From what I know about your specific case, Product is a data object (like Integer, Long, BigDecimal). It just encodes state without much functionality of its own.

If that's true, it should be simple to create test cases without mocking. If you need mocking for data objects, then something is wrong with your code. Mocking is only needed for things like services - code which acts upon data objects and which has external dependencies which you need to cut for a test.

The second argument is that you're writing tests that pass but which don't tell a story. It's a complex form of having 10'000 tests that only contain assertTrue(true);. While it's a nice thing to have in terms of test count, it doesn't give you a single advantage over not having them at all.

Upvotes: 1

Related Questions