Summary
I'm trying write a unit test using Gut for my player in gdscript but calling get_position() on the player (a KinematicBody2D) is causing the following error:
ERROR: get_global_transform: Condition "!is_inside_tree()" is true. Returned: get_transform()
At: scene/2d/canvas_item.cpp:467.
ERROR: body_test_motion: Condition "!body->get_space()" is true. Returned: false
At: servers/physics_2d/physics_2d_server_sw.cpp:1046.
ERROR: get_global_transform: Condition "!is_inside_tree()" is true. Returned: get_transform()
At: scene/2d/canvas_item.cpp:467.
ERROR: body_test_ray_separation: Condition "!body->get_space()" is true. Returned: false
At: servers/physics_2d/physics_2d_server_sw.cpp:1058.
Expectation
I was expecting that after _physics_process() I would be able to get the updated position of my player but it returns Vector2(0, 0).
Resources
This is my first time using GDScript so I have been using a mixture of the following resources in an attempt to write this first test:
Failed solutions
I think I may need to make the player a child of something else but I'm unsure how to do this within my test.
I tried searching the Gut issues on how to use add_child() within a test but I couldn't find an answer.
I also tried making the player a child of an Area2D but that didn't seem to work either:
var player := Player.new(input)
var area := Area2D.new()
area.add_child(player)
Code
This is the code that is causing the error when calling gut from the command line:
test/unit/actors/test_player.gd
extends "res://addons/gut/test.gd"
func test_can_create_player() -> void:
var input = MockInput.new()
var player := Player.new(input)
assert_not_null(player)
func test_can_move_player_up() -> void:
var input = MockInput.new()
input.press("ui_up")
var player := Player.new(input)
simulate(player, 1, .1)
assert_eq(player.get_position(), Vector2(200, 0))
test/mock_input.gd
class_name MockInput
var _pressed: Dictionary = {}
func press(key: String) -> void:
_pressed[key] = true
func release(key: String) -> void:
_pressed[key] = false
func is_action_pressed(key: String) -> bool:
if _pressed.has(key):
return _pressed.get(key)
return false
entities/actors/player.gd
extends KinematicBody2D
class_name Player
export var speed: int = 200
var _input: Object = Input
var _velocity: Vector2 = Vector2()
func _init(input: Object = Input):
_input = input
func _physics_process(_delta: float) -> void:
_velocity = Vector2()
if _input.is_action_pressed("ui_right"):
_velocity.x += 1
if _input.is_action_pressed("ui_left"):
_velocity.x -= 1
if _input.is_action_pressed("ui_down"):
_velocity.y += 1
if _input.is_action_pressed("ui_up"):
_velocity.y -= 1
_velocity = _velocity.normalized() * speed
_velocity = move_and_slide(_velocity)