2016-04-28 2 views
0

Имеют реализацию класса формы геометрии, которая выглядит примерно так:Как сравнить результат геометрии от геометрии. Допустим, с помощью Geometry.Empty?

private readonly IShapeModel _shape; 

    public Shape(IShapeModel shape) : base(shape) 
    { 
     _shape = shape; 
    } 

    /// <summary> 
    /// Specific geometry data of the shape 
    /// </summary> 
    public string GeometryData => _shape.GeometryData; 

    /// <summary> 
    /// Returns the <see cref="Geometry"/> for this shape 
    /// </summary> 
    public Geometry Geometry => Geometry.Parse(GeometryData); 

Как вы можете видеть, я обеспечиваю модель в форме и позволяет вернуть объект геометрии со стандартным методом Разбор предоставленной геометрии.

Код отлично работает и возвращает пустую геометрию, когда не задано значение GeometryData.

Теперь я хочу, чтобы проверить его с чем-то вроде этого:

[TestMethod] 
    public void AccessGeometryPropertyWithNoGeometryDataSetShouldReturnEmpty() 
    { 
     var shape = new TestShapeModel {GeometryData = null}; 
     _shapeViewModel = new Shape(shape); 
     var expected = Geometry.Empty; 
     var actual = _shapeViewModel.Geometry; 
     Assert.AreEqual(expected, actual); 
    } 

Хотя проблема Geometry.Empty кажется, возвращает новый экземпляр, который не равен результату, например разбираемых.

Хотя оба объекта идентичны. Я получаю этот результат: Дополнительная информация: Assert.AreEqual не удалось. Ожидается: <>. Фактический: <>.

Как я пришел с этим:

[TestMethod] 
    public void AccessGeometryPropertyWithNoGeometryDataSetShouldReturnEmpty() 
    { 
     var shape = new TestShapeModel {GeometryData = null}; 
     _shapeViewModel = new Shape(shape); 
     Assert.IsTrue(IsEmptyGeometry(_shapeViewModel.Geometry)); 
    } 

    /// <summary> 
    /// Check if Geometry is empty by comparing Empty Bounds. 
    /// </summary> 
    private static bool IsEmptyGeometry(Geometry geometry) 
    { 
     var result = false; 
     var expected = Geometry.Empty; 
     if (geometry != null) 
     { 
      result = (geometry.Bounds == expected.Bounds); 
     } 
     return result; 
    } 

Есть ли лучший подход для решения этой проблемы? Я бы ожидал чего-то в самой структуре, чтобы сравнить с Geometry.Empty без переопределения Equals или реализации этого кода выше.

+2

[ 'Geometry.IsEmpty()'] (https://msdn.microsoft.com /en-us/library/system.windows.media.geometry.isempty(v=vs.110).aspx)? –

ответ

1

Если геометрия не реализована вами на всех, вы можете взять ваш метод IsEmptyGeometry и сделать его и используйте его, чтобы сделать ваше утверждение «хорошим».

public static class GeometryExtensions 
{ 
    public static bool IsEmpty(this Geometry geometry) 
    { 
     var result = false; 
     var expected = Geometry.Empty; 

     if (geometry != null) 
     { 
      result = (geometry.Bounds == expected.Bounds); 
     } 

     return result; 
    } 
} 

Тогда вместо того, чтобы сделать это:

[TestMethod] 
    public void TestEmptyGeometry() 
    { 
     var shape = new TestShapeModel { GeometryData = null }; 
     _shapeViewModel = new Shape(shape); 
     var expected = Geometry.Empty; 
     var actual = _shapeViewModel.Geometry; 
     Assert.AreEqual(expected, actual); 
    } 

Вы можете сделать это:

[TestMethod] 
    public void TestEmptyGeometry() 
    { 
     var shape = new TestShapeModel { GeometryData = null }; 
     _shapeViewModel = new Shape(shape); 
     var actual = _shapeViewModel.Geometry; 
     Assert.IsTrue(actual.IsEmpty()); 
    } 
+0

Использование метода расширения действительно делает его более элегантным для тестирования. Я мог бы рассмотреть возможность изменения/удаления нулевой проверки в этом случае. Я буду голосовать за этот ответ, чтобы быть лучшим подходящим решением. –

+0

Как ни странно, я полностью упускал из виду тот факт, что уже существует метод IsEmpty() в рамках, например, Damien_The_Unbeliever. В конечном итоге это решение устарело. –

0

Assert.Equals использует сравнение сравнений между объектами, поэтому вы должны переопределить метод Equals объекта System.Object, чтобы он работал, сравнивая два объекта Geometry. Я не знаю вашей реализации геометрии, поэтому я собираюсь предположить, как основные работы связаны с тем, что вы объяснили.

Я предполагаю, что то, что делает одну геометрию похожей на другую, - это те же границы. В вашем случае это должно быть более сложным, поэтому рассмотрим это в моем примере.

Вот кончик, что делать в вашем классе геометрии.

public class Geometry 
{ 
    // I don't know what is the implementation of bounds, so 
    // I'm just assuming that is something comparable here. 
    public Rectangle Bounds { get; set; } 

    // Here's your definition of Geometry.Empty, from what I understood. 
    public static Geometry Empty 
    { 
     get 
     { 
      return new Geometry { Bounds = new Rectangle(0, 0, 0, 0) }; 
     } 
    } 

    // Here is the key: you must override the default operators of equality 
    // and difference to make comparations to work, because internally it will 
    // use them. 
    public static bool operator ==(Geometry left, Geometry right) 
    { 
     if (left == null && right == null) 
     { 
      return true; 
     } 

     if (left != null && right != null) 
     { 
      return left.Bounds == right.Bounds; 
     } 

     return false; 
    } 

    public static bool operator !=(Geometry left, Geometry right) 
    { 
     if (left == null && right == null) 
     { 
      return false; 
     } 

     if (left != null && right != null) 
     { 
      return left.Bounds != right.Bounds; 
     } 

     return true; 
    } 

    // I recommend you to override Equals method of 
    // System.Object too. For Assert.AreEqual to work, 
    // actually this method will be used. 
    public override bool Equals(object obj) 
    { 
     var objAsGeometry = obj as Geometry; 

     if (obj == null) 
     { 
      return false; 
     } 

     return objAsGeometry.Bounds == this.Bounds; 
    } 

    // GetHashCode is used in some types of comparations too, 
    // altough not in your case with Assert.AreEqual. 
    // If you want to make a fully comparable object, 
    // be sure to override it too, with all conditions used 
    // to compare one Geometry object with other. 
    public override int GetHashCode() 
    { 
     return Bounds.GetHashCode(); 
    } 
} 

Делая это, тест, который сравнить два объекта Geometry.Empty должны пройти:

[TestClass] 
public class GeometryTests 
{ 
    [TestMethod] 
    public void TestTwoEmptyGeometries() 
    { 
     var geometry1 = Geometry.Empty; 
     var geometry2 = Geometry.Empty; 

     // Pass 
     Assert.AreEqual(geometry1, geometry2); 
    } 
} 
+0

Я подозреваю, что они говорят об этом [https://msdn.microsoft.com/en-us/library/system.windows.media.geometry (v = vs.110) .aspx) Класс 'Geometry', т. Е. Не один из своих. –

+0

Ну, если геометрия не реализована им, то Assert.Equals не будет работать вообще, потому что сам класс не сопоставим с этим методом.Затем я предложил бы использовать этот метод IsEmpty и сделать его методом расширения, чтобы вместо этого он мог вызвать Geometry.IsEmpty(). – Ismael