2012-04-06 6 views
1

Ich versuche DataBinding innerhalb einer WinForm-Anwendung zu testen. Der folgende Testfall schlägt fehl.Wie WinForm DataBinding testen?

[Test] 
public void TestOneWayEntityBinding() 
{ 
    //Arrange 
    var entity = new MyEntity(); 
    entity.SomeProperty = "someValue"; 
    var userControl = new MyUserControl(); 
    const string pattern = @"xxx"; 

    //Act 
    userControl.textBox.DataBindings.Add("Text", entity, "SomeProperty"); 
    userControl.textBox.Text = pattern; 

    //Assert 
    Assert.AreEqual(pattern, entity.SomeProperty); 
} 

Sogar explizite Aufruf b.WriteValue() auf die Bindungsinstanz b, funktioniert nicht.

Danke, Marcello.

+0

Überraschen! Durch Hinzufügen des folgenden Codes im Arrangierabschnitt wird der Test bestanden. Formular f = new Form(); f.Controls.Add (entiIntervenutiUserControl); f.Show(); ... Es scheint, dass Datenbindung nur auf Steuerelemente wirkt, die einem sichtbaren Formular zugeordnet sind. – Marcello

+0

Sorry, ich habe vergessen zu sagen, dass auch b.WriteValue() aufgerufen werden muss, wobei b die von DataBindings.Add (...) zurückgegebene Binding-Instanz ist. Andernfalls, wie unten von lazyberezovsky vorgeschlagen, können Sie binden mit DataBindings.Add ("Text", Entität, "Altri", True, DataSourceUpdateMode.OnPropertyChanged); – Marcello

+0

Also, welcher Teil Ihrer Frage wird von meiner Antwort nicht beantwortet? –

Antwort

2

Es scheint, als ob Sie versuchen, .Net-Framework zu testen. Sie sollten keine Tests für Code schreiben, den Sie nicht besitzen. Eine gute Option ist hier der Abnahmetest, der auf die Benutzeroberfläche wirkt (z. B. White), indem TextBox-Text festgelegt wird.

Btw, warum textBox ist öffentlich in Ihrer Benutzerkontrolle? Die Implementierung sollte verborgen werden. Es ist gut, Eigenschaft wie 'Muster' des Typs string zu haben. Und Sie sollten diese Datenbindung, die in Ihrer Kontrolle verwendet wird, nicht veröffentlichen. Also, wenn Sie wollen, wird nicht UI ausüben, dann guter Test für die Kontrolle sein:

[Test] 
public void ShouldUpdateEntityWhenPatternChanged() 
{ 
    //Arrange 
    var entity = new MyEntity() { SomeProperty = "someValue" };  
    var userControl = new MyUserControl() { Entity = entity }; 
    const string pattern = @"xxx"; 

    //Act  
    userControl.Pattern = pattern; 

    //Assert 
    Assert.That(entity.SomeProperty, Is.EqualTo(pattern)); 
} 

Ideale zum Schein Einheit sein würde, und überprüfen nur, dass SomeProperty wurde eingestellt, weil zur Zeit Test in zwei Gründen fehlschlagen könnte : Textfeld ist nicht an SomeProperty gebunden, oder SomeProperty Setter funktioniert falsch.

UPDATE Look here warum Bindung funktioniert nicht nach dem programmgesteuerten Festlegen von Text. Um eine Bindung zu aktualisieren, wenn Eigenschaft statt, wenn seine Validieren, Nutzungsänderungen:

textBox.DataBindings.Add("Text", entity, "SomeProperty", true, DataSourceUpdateMode.OnPropertyChanged); 

UPDATE wie Kontrolle Scheint sollte für die Validierung sichtbar sein. Wenn Sie nicht DataSourceUpdateMode ändern möchten, und Sie laufen nicht Ihre Tests auf Service ohne UI, dann einfach ControlTester wird Ihnen helfen:

public class ControlTester : IDisposable 
{ 
    private Form _form = new Form(); 

    public ControlTester(Control control) 
    { 
     _form = new Form(); 
     _form.Controls.Add(control); 
     _form.Show(); 
    } 

    public void Dispose() 
    { 
     _form.Close(); 
    } 
} 

es verwenden, wenn auf Kontrolle im Test handeln:

using(new ControlTester(userControl)) 
    userControl.Pattern = pattern; 

LETZTE UPDATE: DataBining funktioniert nicht für die Kontrolle, die nicht erstellt wurde. Also hier Optionen:

  • erstellen gefälschte Form (mit ControlTester)
  • Run echte Form
  • Aufruf Create() nach der Instanziierung es

Ich denke letzte Option ist die beste. Damit DataBinding im Test funktioniert, können Sie einfach die CreateControl() -Methode aufrufen:

+0

Ok, ok. Eigentlich wird der Bereich nicht wie in der Frage gezeigt manuell erstellt. Es wird von einer "Auto-Wire-Up" -Engine ausgeführt, die die Datenbindung basierend auf aspektorientierten Attributen für Entitäten verwaltet. Der Testfall sollte die korrekten Verdrahtungen testen. – Marcello

+0

@Marcello, ich habe eine Testprobe für Sie hinzugefügt. In deinem ursprünglichen Test hast du auf textBox und nicht auf userControl reagiert, was getestet werden sollte. –

+0

textBox ist nicht öffentlich, aber intern. Das Unit-Test-Projekt greift auf Internals durch die InternalsVisibleTo-Klausel im getesteten Projekt zu. Ich stimme der Verspottung der Entität zu: sehr nützlicher Hinweis. Vielen Dank! – Marcello