2016-10-04 1 views
2

Так у меня есть класс Doorcontrol, который может иметь 4 состоянияКак вызвать функцию только, когда в конкретном случае в случае коммутатора для модульного теста?

public enum DoorControlState 
{ 
    DoorClosed, 
    DoorOpening, 
    DoorOpen, 
    DoorBreached 

} 

Чтобы открыть дверь accescode необходима, код затем проверяется и если это правильно дверь открыта. Если дверь не находится в закрытом состоянии, ничего не должно произойти. Он должен выглядеть так: RequestEntry (id) [Doorcontrol] -> ValidateEntryRequest (id) [IUserValidation] -> OK [Doorcontrol] -> Открыть [IDoor] -> изменить состояние на DoorOpening. Затем Idoor вызывает DoorOpen, и состояние изменяется на DoorOpen и так далее.

я реализовал класс DoorControl следующим

public class DoorControl 
{ 
    private IDoor _door; 
    private IEntryNotification _entryNotification; 
    private IUserValidation _userValidation; 
    private DoorControlState _doorControlState; 
    private int _id; 

    public DoorControl(IDoor door, IEntryNotification entryNotification, IUserValidation userValidation, DoorControlState doorControlState) 
    { 
     _door = door; 
     _entryNotification = entryNotification; 
     _userValidation = userValidation; 
     _doorControlState = doorControlState; 
    } 

    public void Run() 
    { 
     switch (_doorControlState) 
     { 
      case DoorControlState.DoorClosed: 

       bool foo = RequestEntryId(); 
       if (foo) 
       { 
        _door.Open(); 
        _doorControlState = DoorControlState.DoorOpening; 
       } 
       break; 
      case DoorControlState.DoorOpening: 
       _door.Close(); 
       _doorControlState = DoorControlState.DoorOpen; 
       break; 
      case DoorControlState.DoorOpen: 
       // Do stuff....     
       break; 
      case DoorControlState.DoorBreached: 
       // Do stuff 
       break; 
      default: 
       throw new InvalidEnumArgumentException(); 
      } 
    } 

    private bool RequestEntryId() 
    { 
     bool maybeFoo = _userValidation.ValidateEnetryRequest(); 
     if (maybeFoo = true) 
     { 
      return true; 
     } 

     return false; 
    } 

    public void DoorOpened() 
    { 
     // 
    } 

    public void DoorClosed() 
    { 
     // 
    } 
} 

}

В UserValidation и дверные классы реализованы как интерфейсы

public interface IUserValidation 
{ 
    bool ValidateEnetryRequest(); 

} 

public interface IDoor 
{ 

    void Open(); 

    void Close(); 

} 

Я проверяю свой код, используя NUnit и NSubstitute

namespace DoorControl.Unit.Test 
{ 
[TestFixture] 
public class DoorControlUnitTest 
{ 
    private DoorControl _uut; 
    private IDoor _door; 
    private IEntryNotification _entryNotification; 
    private IUserValidation _userValidation; 
    private DoorControlState _doorControlState; 

    [SetUp] 

    public void SetUp() 
    { 
     _door = Substitute.For<IDoor>(); 
     _entryNotification = Substitute.For<IEntryNotification>(); 
     _userValidation = Substitute.For<IUserValidation>(); 
     _doorControlState = DoorControlState.DoorClosed; 

    _uut = new DoorControl(_door, _entryNotification, _userValidation, _doorControlState); 
    } 

    [Test] 
    public void InputCorrectId() 
    { 
     _userValidation.ValidateEnetryRequest().Returns(true); 
     _uut.RequestEntryId(); // Can't called that cause it's private 

     _door.Received().Open(); 

    } 

} 
} 

Я не могу понять, как заставить его вызывать RequestEntryId только тогда, когда он находится в состоянии «Закрыто» и игнорирует его, если он находится в другом состоянии.

Редактировать: Что означает, что Doorcontrol находится внутри, должно быть скрыто от всех остальных.

+0

Рассмотрите возможность применения шаблона стратегии вместо использования операторов switch – Nkosi

ответ

1
public void InputCorrectId() 
    { 
     _userValidation.ValidateEnetryRequest().Returns(true); 
     if(_doorControlState == DoorControlState.DoorClosed){ 
      _uut.RequestEntryId(); // Make it public 
     } 
     _door.Received().Open(); 

    } 

Или в класс doorcontrol как:

case DoorControlState.DoorClosed: 
    RequestEntryId(); 
+0

Для этого требуется, чтобы мой тест знал состояние DoorControl. Я бы хотел, чтобы кто-нибудь не знал, в каком состоянии находится DoorControl. –

+0

запускайте его в управление запуском класса, я обновил свой ответ – Aschab

+0

У меня была ошибка в коде где-то еще, что мешало мне заставить его работать, как только это исправлено, это сработало так, как должно. Thx для помощи –

0

Я не уверен, что именно вы спрашиваете: когда вы говорите: «Я не могу понять, как сделать это только позвонить RequestEntryId когда он находится в состоянии «Закрыто» и игнорирует его, если он находится в другом состоянии ». вы имеете в виду единичный тест? Я не могу понять, почему вы хотите это сделать. Пожалуйста, предоставьте дополнительную информацию, и я обновлю этот ответ, если смогу помочь.

Я заметил несколько вещей, которые могут вам помочь. Во-первых RequestEntryId есть проблема:

private bool RequestEntryId() 
{ 
    bool maybeFoo = _userValidation.ValidateEnetryRequest(); 
    if (maybeFoo = true) 
    { 
     return true; 
    } 
    return false; 
} 

Здесь maybeFoo = true это задание, которое перезаписывает результат ValidateEntryRequest(). Я думаю, что вы хотели сравнить с ==, но и весь метод может быть упрощена:

private bool RequestEntryId() 
{ 
    return _userValidation.ValidateEnetryRequest(); 
} 

С, что фиксируется мы можем запустить несколько тестов, чтобы проверить, как Run метод общественного ведет себя. Учитывая, что ваш SetUp создает управление дверью уже в состоянии Closed, мы можем проверить, что дверь открывается для действительных пользователей и не открывается для недействительных пользователей.

[Test] 
    public void ClosedDoorOpensWhenUserIsValid() 
    { 
     _userValidation.ValidateEnetryRequest().Returns(true); 
     _uut.Run(); 
     _door.Received().Open(); 
    } 

    [Test] 
    public void ClosedDoorDoesNotOpenWhenUserInvalid() 
    { 
     _userValidation.ValidateEnetryRequest().Returns(false); 
     _uut.Run(); 
     _door.DidNotReceive().Open(); 
    } 

Мы также можем проверить проверки не повторяются для уже открытой двери:

[Test] 
    public void OpenDoorDoesNotRevalidate() 
    { 
     _userValidation.ValidateEnetryRequest().Returns(true); 
     _uut.Run(); 

     _userValidation.ClearReceivedCalls(); 
     _uut.Run(); 
     _userValidation.DidNotReceive().ValidateEnetryRequest(); 
    } 

Надеется, что это дает вам некоторые идеи для тестирования этого.

Смежные вопросы