Testing UI Elements

Hi

I really like the new UI Toolkit!
I now try to write unit tests and I’m facing some problems.

I have a Wapper Class which is using a TextField and Registers some Callbacks. Now I want to Invoke these Callbacks to test if everything is working fine.

But no matter which way I took I was not able to solve this.
I already tried this solution: ( Testing custom elements ) but it did not work out for me, so I undid the changes.

Attached the class and test class.

Can someone help me with this case?

public class TextFieldWrapper : ITextFieldWrapper
    {
        // Dependencies
        private readonly TextField m_TextField;

        // Events
        public event EventHandler<string> ValueChanged;
       
        // Properties
        public string Value
        {
            get => m_TextField.value;
            set => m_TextField.value = value;
        }
       
        // Constructors
        public TextFieldWrapper(TextField textField)
        {
            m_TextField = textField;
            m_TextField.RegisterCallback<FocusOutEvent>(HandleFocusOut);
            m_TextField.RegisterCallback<KeyDownEvent>(HandleKeyDown);
        }

        private void HandleKeyDown(KeyDownEvent evt)
        {
            if(evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)
                ValueChanged?.Invoke(this, m_TextField.value);
        }

        private void HandleFocusOut(FocusOutEvent evt)
        {
            ValueChanged?.Invoke(this, m_TextField.value);
        }
    }
[TestFixture, Category("UnityTest")]
    public class TextFieldWrapperTests
    {
        private TextField m_TextField;
        private TextFieldWrapper m_TextFieldWrapper;
       

        [SetUp]
        public void SetUp()
        {
            m_TextField = new TextField();
            m_TextFieldWrapper = new TextFieldWrapper(m_TextField);
        }

        [Test]
        public void Should_SetValue_When_PropertyIsCalled()
        {
            var newValue = "newValue";
            m_TextFieldWrapper.Value = newValue;
           
            Assert.That(m_TextField.value, Is.EqualTo(newValue));
        }
       
        [Test]
        public void Should_ReturnValue_When_PropertyIsCalled()
        {
            var newValue = "newValue";
            m_TextField.value = newValue;
           
            Assert.That(m_TextFieldWrapper.Value, Is.EqualTo(newValue));
        }
       
        [Test, Ignore("No solution found for firing events within tests")]
        public void Should_RaiseEvent_When_FocusOut()
        {
            var called = 0;
            m_TextFieldWrapper.ValueChanged += (sender,args) => called++;

            using (var focusOutEvent = FocusEvent.GetPooled())
            {
                focusOutEvent.target = m_TextField;
                m_TextField.SendEvent(focusOutEvent);
            }
            Assert.That(called, Is.EqualTo(1));           
        }

Hi @CMC-Kiesel_Markus

You’re on the right track. Instead of sending focus events, you should call the Focus() and Blur() methods on the focusable element itself.

Hi @etienne_unity

thank you for the quick feedback! I tried your solution by calling Focus instead of sending the event.
But it seems like it does not trigger my registered event.

I have the feeling that it is probably because the TextField ist currently not on a IPanel and therefore a lot of stuff in the background will not work as expected?

Is there anything like a “Test”-Panel which I can use?