Как правильно удалить объект, который наследует интерфейс из списка ILine в void functionR emove при выполнении данного модульного теста в C#? - PullRequest
0 голосов
/ 07 января 2020

У меня есть interface ILine, который наследуется class Line. ILine определяется следующим образом:

interface ILine {

    string Name { get; }
    ICity City { get; }
    IEnumerable<IStation> Stations { get; }
    IEnumerable<ITrain> Trains { get; }

    IStation Previous(IStation s);
    IStation Next(IStation s);
    void AddBefore(IStation toAdd, IStation before = null);
    void Remove(IStation s);

}

В текущем контексте, с которым я работаю в методе void Remove (IStation s), и я пытаюсь пройти следующий модульный тест, который позволяет удалить станции тестирования, а затем повторно добавлено.

Юнит-тест:

public void stations_can_be_removed()
{
    ICity c = CityFactory.CreateCity("Paris");
    ILine l = c.AddLine("RER B");
    IStation s = c.AddStation("Opera", 0, 0);
    Action action = (() => l.Remove(s));
    action.ShouldThrow<ArgumentException>();
    l.AddBefore(s);
    action = (() => l.Remove(s));
    action.ShouldNotThrow();
    l.Stations.Count().Should().Be(0);
    s.Lines.Count().Should().Be(0);
}

public void stations_can_be_removed_then_re_added()
{
    ICity c = CityFactory.CreateCity("Paris");
    ILine l = c.AddLine("RER B");
    IStation s = c.AddStation("Opera", 0, 0);

    l.AddBefore(s);
    s.Lines.Count().Should().Be(1);
    l.Remove(s);
    s.Lines.Count().Should().Be(0);

    Action action = (() => l.AddBefore(s));
    action.ShouldNotThrow();
    l.Stations.Count().Should().Be(1);
    s.Lines.Count().Should().Be(1);
}

Я попытался выполнить следующий код, чтобы пройти тест в основном в функции void Remove. Тем не менее, модульный тест прерывается в строке 7, где я выкидываю исключение. Я думаю, что мой подход неверен, как тестировать этот модульный тест, в основном так, как я определил свое исключение:

if (((List<ILine>)s.Lines).Remove(s))
{
    throw new ArgumentException();
}
public IEnumerable<IStation> Stations
{
    get{ return _stations; }
}

public IStation Next(IStation s)
{
    if (!_stations.Contains(s)) 
      throw new ArgumentException();
    var index = _stations.IndexOf(s);
    var isLast = index == _stations.Count -1;
    if (isLast) { return null;}
    return _stations[index + 1];
}

public IStation Previous(IStation s)
{
    if (!_stations.Contains(s))
        throw new ArgumentException();
    var index = _stations.IndexOf(s);
    var isFirst = index == 0;
    if (isFirst) { return null;}
    return _stations[index - 1];
}

public void AddBefore(IStation toAdd, IStation before = null)
{
    if (toAdd == null || _stations.Contains(toAdd)) 
        throw new ArgumentException();
    ((List<Line>)toAdd.Lines).Add(this);

    var index = (before != null) ? _stations.IndexOf(before) : -1;
    if (index > -1)
        _stations.Insert(index, toAdd);
    else
        _stations.Add(toAdd);
}

public void Remove(IStation s)
{
    _stations.Remove(s);
    if (((List<ILine>)s.Lines).Remove(s))
        throw new ArgumentException();

}

1 Ответ

0 голосов
/ 08 января 2020

List<T>.Remove() возвращает true при успешном выполнении, поэтому выдает исключение в соответствии с указаниями вашего кода.

Возможно, вы захотите выдать указанное исключение, если не завершится успешно:

if (!((List<ILine>)s.Lines).Remove(s))

Но речь идет о десятом вопросе об этом дизайне, пять из которых вы или другие удалили, и, как я предлагал при нескольких предыдущих вызовах, вы можете захотеть поцарапать этот дизайн и начать все сначала. , List<ILine> не может содержать IStation, если IStation не наследует ILine, что не логично (наследование подразумевает отношение is-a, а станция не линия).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...