如何在单个测试的开关盒中的特定情况下调用一个函数?

时间:2016-10-04 01:03:04

标签: c# nunit nsubstitute

所以我有一个门控制,可以有4个状态

public enum DoorControlState
{
    DoorClosed,
    DoorOpening,
    DoorOpen,
    DoorBreached

}

要打开门,需要一个访问代码,然后验证代码,如果正确,则打开门。如果门未处于关闭状态,则不会发生任何事情。它应该像这个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和Door类实现为Interfaces

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();

    }

}
}

我无法弄清楚如何只在它处于Doorclosed状态时调用RequestEntryId,如果它处于另一个状态则忽略它。

编辑:Doorcontrol所处的状态应该对其他人隐藏。

2 个答案:

答案 0 :(得分:1)

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

    }

或者进入门控类:

 case DoorControlState.DoorClosed:
    RequestEntryId();

答案 1 :(得分:0)

我不确定你究竟在问什么:当你说&#34;我无法弄清楚如何只在它关闭时才能调用RequestEntryId陈述,如果它处于另一个状态,则忽略它。&#34;你的意思是单元测试吗?我无法弄清楚你为什么要那样做。请提供更多信息,如果我能提供帮助,我会更新此答案。

我注意到了一些可能对你有帮助的事情。首先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();
    }

希望这能为您提供一些测试方法。