Balancing Design Principles: Unit Testing

I am writing a bananagram simulation. I currently have a GameMaster class that supports a common collection of works. The deal(Player) method uses a certain number of parts for this player.

I want to write unit tests for this. However, at the moment I have no getters and, therefore, there is no way to check the status of objects.

Why not add getters? I do not want to add code to the open interface just for testing. Right now, there is no other reason to uncover these features.

What am I supposed to do here? In any case, add getters cluttering the public API (or hoping they will be needed in the future)? Reject unit testing? (Sounds like a bad idea.)

Or does this indicate that my open interface is corrupted?

+2
source share
8 answers

Instead of relying on a specific instance of the Player, write your unit tests on the interface (or equivalent) and rely on mocks or other interaction to confirm not that the player is in the correct state, but simply that the right calls (in terms of GameMaster class.

If you cannot verify the correct behavior of the GameMaster class without relying on end-state confirmation, this is a sign that your responsibilities are inappropriate. GameMaster should be responsible for informing the Player what happened, while the Player should be responsible for taking the appropriate action.

This is also useful because it means that tests for GameMaster will depend only on the behavior of the GameMaster class, and it will not need to be touched if the Player class changes its behavior.

Avoid adding getters for unit tests. When you are tempted to add a getter, look instead at using interaction testing (as I just described) instead of state testing.

+3
source

There are several ways to verify that part of the code is working. The first thing most of us think is state-based testing (i.e., using getters to verify that the final state of your facility is what you think should be). However, another way to verify that your code is working is to use behavior or interaction testing.

Martin Fowler has a decent article on the difference here

+2
source

You should check the functionality that internally uses these state variables. If a public function is not used, then they are dead code.

0
source

I would say that your classes can do too much. It looks like you have a state repository and other things.

Consider making testing easier. How would you test them if you shared state and logic? Instead of just calling

 GameMaster gameMaster = new GameMaster; playerOne.Score = gameMaster.ComputePlayerScore(newScore); 

you will pass a GameState instance containing only state to the GameMaster procedure constructor:

 GameState gameState = new GameState; GameMaster gameMaster = new GameMaster(gameState); playerOne.Score = gameMaster.ComputePlayerScore(newScore); 

Your unit test routines can then pass any data they need for gameState and newScore, and check the results in gameState after they return. Dependency Injection is your friend.

0
source

One thing you can do is subclass your main class to provide recipients for testing. It would be easier if you had interfaces for work.

A subclass for providing getters is a semi-dangerous proposition. If you just provide getters for internal properties, the damage will be minimal, but you need to be careful that you test the actual class, not the derived version.

0
source

I see nothing wrong with adding code specifically for verification. Unit tests are invaluable for regression testing.

However, it also fixes that it should not affect your public API. Therefore, I propose creating protection against getters and placing your unit tests in the same package as the Player class. (In a different source folder, however, so that you have a clear separation between the production code and the test code.)

0
source

unit tests do not improve your code , they make your application more stable over time with changes and added features. therefore, if you do not have public getters in your GameMaster class, you do not need to create them for unit tests.

no getters mean that your interface is leaking, the test development concept is the minimum code for writing a test (which follows from the requirement), if you do not need you to write. print, trace, log will be here long after the unit tests disappear (normal, they are also here to stay, but in many cases excessive and excessive)

0
source

What am I supposed to do here? Either way, add getters cluttering up the open API (or hoping they will be needed in the future)?

I do not get this answer. How does a getter clutter up?

You are testing. Design is driven by the absolute need to test everything.

Getters are not "messy." They are how you check things.

"Reject unit testing?"

I do not think it's a good idea.

-6
source

Source: https://habr.com/ru/post/893101/


All Articles