This was working and now does not. This is for a pretty simple page. I use DevExpress and emailTextBox is a DxTextBox.
This is successful
var emailTextBox = allTextBoxes.Single(x => x.Instance.InputId == "email");
emailTextBox.TextEditChange("");
button.Click();
var li = renderedComponent.Find("li.validation-message");
Assert.NotNull(li);
Assert.Equal("Your Email is required", li.InnerHtml);
Assert.Equal("", pageModel.Email);
Then this code immediately follows - and fails.
emailTextBox.TextEditChange("bogus");
button.Click();
li = renderedComponent.Find("li.validation-message");
Assert.NotNull(li);
Assert.Equal("The Email field is not a valid e-mail address.", li.InnerHtml);
Assert.Equal("bogus", pageModel.Email);
The problems are:
- The error message it finds is the message for an empty field.
pageModel.Emailis "".- In the debugger I look at
emailTextBox.Textand it is "".
Is TextEditChange() not the right way to set the value in DxTextBox?
Update:
And sometimes randomly the above 2nd test passes, but then the next test, which is similar, fails. These tests assume that not only the <input> value is being set, but that the <DataAnnotationsValidator/> and <ValidationSummary/> have then run.
Update 2:
The following works:
emailTextBox.TextEditChange("bogus");
button.Click();
renderedComponent.Render();
li = renderedComponent.Find("li.validation-message");
Assert.NotNull(li);
Assert.Equal("The Email field is not a valid e-mail address.", li.InnerHtml);
Assert.Equal("bogus", pageModel.Email);
Is it required to call renderedComponent.Render() after the TextEditChange/Click?
I got a lot of help from the bUnit team on this and the fundamental answer is twofold.
First, I need to make each
TextEditChange()&Click()test a separate unit test. Doing several in a row is asking for trouble because the page elements all stay the same and it's just the text that changes.Second, do a
WaitFor, usually on therenderedComponent.Find()with a timeout. The unit test thereby tests for the expected change not by asserting the value, but by throwing an exception if the expected change does not get rendered before the timeout.