What is a good Unit Test Practice for mocking a fake model that changes a lot?

182 views Asked by At

I'm trying to test this custom model where if some values are null, it wouldn't be a valid model. My custom model is defined in it's own class as:

public CustomModel(String FirstName, String LastName, String address, String phone)

...so on and so forth (there are more fields but we'll just use these for now as an example).

Now in my test, I create a dummy model by doing this (validator is a helper class that checks if it's null or not this is not important):

@Before
public void setUpBefore()
{
    _customTestModel = new CustomModel("First", "Last", "123 Address", "1234567890");
}

And then as a test example, I would do:

@Test
public void testNotValidModel_NullLastName()
{
    setUpBefore();
    _customTestModel.put(1, null);
    assertFalse(validator.test(null, _customTestModel));
}

My problem is, if I do need to change how I want to structure my custom model, say I want to do it like this now:

public CustomModel(String LastName, String FirstName, String phone, String address)

I would need to go back into my test and re-do my _customTestModel and also need to go into each of my tests and change the .put(1, null) to .put(0, null) to the proper slot.

I realize my test is very brittle and I would have to go into the test EVERY time I want to change the customModel. How should I go about fixing this?

1

There are 1 answers

2
djechlin On BEST ANSWER

The entire point of type safety is that if you change the signature, you are required to change code that uses the signature. And the entire point of unit testing is that you call newly written code from the unit test. So if you change existing code, your client must break, and if you add new code, you must add a unit test for it. The system is working as intended.

Any solution I could give you is just a way to circumvent that. For example, you could retain the old constructors as legacy. Usually I prefer to keep my unit tests up to date rather than let them block getting rid of legacy code though.

If you had production clients who were in some sense complaining, then you would have a case for retaining legacy models, or adding a builder pattern, or some other solution. You would then need to define logic to maintain incomplete models and add even more unit test coverage to cover both the old and new code. But this is the opposite of what you are hoping for.