如何单独测试“console.readLine”无效输入?

时间:2013-07-26 18:36:29

标签: c# .net visual-studio-2010

我正在抓住这个小问题。

我在方法

中有这一行和其他3个类似的行
try
{
    int PhoneIMEINumber = int.Parse(Console.ReadLine());
}

{
catch(Exception)
{
    return null;
}

如果用户输入“abcd”进行输入,则抛出异常,我可以捕获它并显示错误消息。

但我如何为此进行单元测试?我无法从单元测试中模拟控制台输入,我想从单元测试中检查是否返回了null。

谢谢

4 个答案:

答案 0 :(得分:8)

您可以使用SetIn

Console.In设置为指定的文本阅读器
var sr = new StringReader("Invalid int");
Console.SetIn(sr);

int? parsed = MethodUnderTest();
Assert.IsNull(parsed);

答案 1 :(得分:8)

如果你想对Console进行单元测试,那么你可能需要创建一个包装器接口。

public interface IConsole
{
    string ReadLine();
}

public class ConsoleWrapper : IConsole
{
    public string ReadLine()
    {
        return Console.ReadLine();
    }
}

这样您就可以创建一个Stub / Fake来测试您的业务规则。

public class TestableConsole : IConsole
{
    private readonly string _output;

    public TestableConsole(string output)
    {
        _output = output;
    }

    public string ReadLine()
    {
        return _output;
    }
}

测试内部:

public class TestClass
{
    private readonly IConsole _console;

    public TestClass(IConsole console)
    {
        _console = console;
    }

    public void RunBusinessRules()
    {
        int value;
        if(!int.TryParse(_console.ReadLine(), out value)
        {
            throw new ArgumentException("User input was not valid");
        }
    }
}

[Test]
public void TestGettingInput()
{
    var console = new TestableConsole("abc");

    var classObject = new TestClass(console);

    Assert.Throws<ArgumentException>(() => classObject.RunBusinessRules());
}

我会尝试避免单元测试Console并依赖它。

答案 2 :(得分:5)

就像发布的两条评论一样。我会考虑重构您的代码以查找更像

的内容
string input = Console.ReadLine();

try
{
    int PhoneIMEINumber = parse_input(input); 
}
catch(Exception)
{
    return null;
}

然后你就有了一个功能

public int parse_input(string input)
{
    return int.Parse(input);
}

然后你要为parse_input函数编写一个单元测试。虽然示例代码看起来很简单,但很难证明在int.Parse()的包装函数周围编写单元测试是合理的,但我假设您的解析在将来会变得更复杂。

答案 3 :(得分:0)

要对代码进行单元测试,那段代码需要是可测试的。

要对方法进行单元测试,我们所做的是传递一些已知的输入并检查它是否返回预期的结果,或者我们是否有正确的副作用。

现在如果你直接在你的方法中输入你的输入,它就不是很可测试了。它有两个部分,读取输入和处理它。如果测试中的断言失败,则您不知道哪个步骤失败。单元测试应针对测试单元或单个责任的代码。

为了使其可测试,请阅读main方法中的输入并将其传递给另一个处理方法(也是面向对象编程的常见概念),并使用已知参数测试第二种方法。