ueb10 1+2

This commit is contained in:
Daniel Langbein 2025-01-16 14:39:42 +01:00
parent 1190b5fec1
commit ff0cbe4973
Signed by: langfingaz
GPG Key ID: 6C47C753F0823002
5 changed files with 256 additions and 0 deletions

View File

@ -0,0 +1,35 @@
<component name="libraryTable">
<library name="junit.jupiter" type="repository">
<properties maven-id="org.junit.jupiter:junit-jupiter:5.9.0" />
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-5.9.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-api-5.9.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/opentest4j-1.2.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-commons-1.9.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/apiguardian-api-1.1.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-params-5.9.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-engine-5.9.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-engine-1.9.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-5.9.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-api-5.9.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/opentest4j-1.2.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-commons-1.9.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/apiguardian-api-1.1.2-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-params-5.9.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-engine-5.9.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-engine-1.9.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-5.9.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-api-5.9.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/opentest4j-1.2.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-commons-1.9.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/apiguardian-api-1.1.2-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-params-5.9.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-jupiter-engine-5.9.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-platform-engine-1.9.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -0,0 +1,23 @@
<component name="libraryTable">
<library name="mockito.core" type="repository">
<properties maven-id="org.mockito:mockito-core:5.12.0" />
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/mockito-core-5.12.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/byte-buddy-1.14.15.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/byte-buddy-agent-1.14.15.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/objenesis-3.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$PROJECT_DIR$/lib/mockito-core-5.12.0-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/byte-buddy-1.14.15-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/byte-buddy-agent-1.14.15-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/objenesis-3.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/mockito-core-5.12.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/byte-buddy-1.14.15-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/byte-buddy-agent-1.14.15-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/objenesis-3.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/specs" />
<excludeFolder url="file://$MODULE_DIR$/tools" />
</content>
@ -19,5 +20,23 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library name="JUnit5.8.1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter/5.8.1/junit-jupiter-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.8.1/junit-jupiter-api-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.8.1/junit-platform-commons-1.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-params/5.8.1/junit-jupiter-params-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-engine/5.8.1/junit-jupiter-engine-5.8.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-engine/1.8.1/junit-platform-engine-1.8.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="mockito.core" level="project" />
<orderEntry type="library" name="junit.jupiter" level="project" />
</component>
</module>

View File

@ -257,6 +257,7 @@ public class LevelModel extends Observable implements Runnable {
int x = (int) (Math.random() * (this.getSizeHeight() - 2));
int y = (int) (Math.random() * (this.getSizeWidth() - 2));
this.groundGrid[x + 1][y + 1] = new DoorModel();
System.out.println("placed exit at " + (x + 1) + "," + (y + 1));
}
/**

View File

@ -0,0 +1,178 @@
package fr.enssat.BoulderDash.models;
import fr.enssat.BoulderDash.helpers.AudioLoadHelper;
import fr.enssat.BoulderDash.helpers.LevelLoadHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
public class LevelModelTest {
private LevelModel levelModel;
DisplayableElementModel[][] groundLevelModel;
LevelLoadHelper levelLoadHelper;
AudioLoadHelper audioLoadHelper;
GameInformationModel gameInformationModel;
@BeforeEach
public void setUp() {
levelLoadHelper = mock(LevelLoadHelper.class);
audioLoadHelper = mock(AudioLoadHelper.class);
gameInformationModel = mock(GameInformationModel.class);
// boundaries and 2x2 field inside
when(levelLoadHelper.getHeightSizeValue()).thenReturn(4);
when(levelLoadHelper.getWidthSizeValue()).thenReturn(4);
when(levelLoadHelper.getRockfordPositionX()).thenReturn(1);
when(levelLoadHelper.getRockfordPositionY()).thenReturn(1);
when(levelLoadHelper.getRockfordInstance()).thenReturn(new RockfordModel());
when(levelLoadHelper.getGroundGrid()).thenReturn(
new DisplayableElementModel[4][4]
);
// We add one diamond below, thus return 1.
when(levelLoadHelper.getDiamondsToCatch()).thenReturn(1);
levelModel = new LevelModel(levelLoadHelper, audioLoadHelper, "game");
// Place diamond next to Rockford
levelModel.getGroundLevelModel()[1][2] = new DiamondModel();
groundLevelModel = levelModel.getGroundLevelModel();
}
/**
* During an ongoing game, the player character is moved to an exit. The following
* behavior is expected and should be verified:
* The game ends.
* The player character is located on the field where the exit was previously located.
* No sound is played.
*/
@Test
void test1bi(){
// Place exit next to Rockford
levelModel.getGroundLevelModel()[2][2] = new DoorModel();
// Move Rockford from (1,1) to (2,2)
levelModel.setPositionOfRockford(2,2);
// Verify:
// Game ended
assertFalse(levelModel.isGameRunning());
// Rockford is located at exit/door
assertEquals(2, levelModel.getRockfordPositionX());
assertEquals(2,levelModel.getRockfordPositionY());
// No sound is played
verify(audioLoadHelper, never()).playSound(anyString());
}
/**
* During an ongoing game, the player character collects the last diamond. The
* following behavior is expected and should be verified:
* The score increases by 1.
* The number of remaining diamonds decreases to 0.
* Exactly one exit appears on the game field.
* The player character is located on the field where the diamond was previously located.
* The starting field of the player character becomes an empty field.
* The sound for collecting a diamond is played.
*/
@Test
void test1bii(){
int oldScore = levelModel.getGameInformationModel().getScore();
int oldRemainingDiamonds = levelModel.getGameInformationModel().getRemainingsDiamonds();
// Verify:
// 1 Remaining diamond
assertEquals(1, oldRemainingDiamonds);
// No exit.
assertEquals(0, numOfExits());
// Move Rockford from (1,1) to (1,2)
levelModel.setPositionOfRockford(1,2);
// Verify:
// Score increased by 1
assertEquals(oldScore + 1, levelModel.getGameInformationModel().getScore());
// No remaining diamonds
assertEquals(0, levelModel.getGameInformationModel().getRemainingsDiamonds());
// Verify: One exit appeared.
// Math.random -> sometimes spawned at old or new position of Rockford,
// then this assertion fails
assertEquals(1, numOfExits());
// Rockford placed at previous diamond location
assertEquals(1, levelModel.getRockfordPositionX());
assertEquals(2,levelModel.getRockfordPositionY());
// The starting field of Rockford becomes an empty field
assertInstanceOf(EmptyModel.class, groundLevelModel[1][1]);
//The sound for collecting a diamond is played.
verify(audioLoadHelper).playSound("coin");
}
int numOfExits(){
// We can't use
// verify(levelModel, times(1)).spawnExit();
// as spawnExit() is a private method.
// Iterate over the ground level and count DoorModel objects.
return (int) Arrays.stream(groundLevelModel)
.flatMap(Arrays::stream)
.filter(x -> x instanceof DoorModel)
.count();
}
/**
* During an ongoing game, the player character collects the last diamond again.
* However, this test case should minimize concrete state changes in the application and instead verify that the appropriate methods are called with the
* correct parameters to achieve the desired behavior. Explain and justify for
* which of the following points this is not possible. The following behavior is
* expected and should be verified:
* The increase in score is triggered.
* The decrease in the number of remaining diamonds is triggered.
* The appearance of an exit on the game field is triggered.
* The update of the player characters position is triggered.
* Replacing the player characters starting field with an empty field is triggered.
* Playing the sound for the entered field is triggered.
*/
@Test
void test1biii(){
GameInformationModel gameInformationModel = mock(GameInformationModel.class);
levelModel.setGameInformationModel(gameInformationModel);
levelModel = spy(levelModel);
// Move Rockford from (1,1) to (1,2)
levelModel.setPositionOfRockford(1,2);
// Verify:
// increase score
verify(gameInformationModel).incrementScore();
// decrease remaining diamonds
verify(gameInformationModel).decrementRemainingsDiamonds();
// exit appearance - IMPOSSIBLE
// 'spawnExit()' has private access
// We can only verify there are no remaining diamonds
verify(gameInformationModel).getRemainingsDiamonds();
// update character's position
verify(levelModel).updateRockfordPosition(anyInt(), anyInt());
// replace with empty field - IMPOSSIBLE
// We can't verify if the field at the position is being emptied,
// because this happens inside the method setPositionOfRockford using a constructor call:
// `this.groundGrid[oldX][oldY] = new EmptyModel();`
assertInstanceOf(EmptyModel.class, groundLevelModel[1][1]);
// play sound
verify(audioLoadHelper).playSound("coin");
}
}