What I'd do is abstract away the Console methods via an interface. Your method shouldn't care about how Console works. You might want to change how you write or read a line later. Something like this:
public interface IConsoleMethods
{
void WriteLine(string message);
string ReadLine();
}
You could implement it the way you did like so:
public class ConsoleMethods : IConsoleMethods
{
public void WriteLine(string message)
{
Console.WriteLine(message);
}
public string ReadLine()
{
return Console.ReadLine();
}
}
You'll have to create a constructor for myData which accepts IConsoleMethods to initialize it. Ideally, you'd want to inject it based on usage.
public class MyData
{
public MyData(IConsoleMethods consoleMethods) { this.console = consoleMethods; }
public IConsoleMethods console;
private string _name;
public void GetData()
{
console.WriteLine("Please Enter your Name(only Alphabet)");
_name = console.ReadLine();
console.WriteLine(_name);
}
}
You could have your original functionality using:
var myData = new MyData(new ConsoleMethods());
myData.GetData();
And, finally, you could test it using a Mock and setting expectations of your new Console
class like so (I've used Moq for mocking):
[TestClass]
public class MyDataTests
{
[TestMethod]
public void GetDataTest()
{
const string expectedDisplayMessage = "Please Enter your Name(only Alphabet)";
const string readString = "test";
var consoleMock = new Mock<IConsoleMethods>();
consoleMock.Setup(c => c.ReadLine()).Returns(readString);
var dd = new MyData(consoleMock.Object);
dd.GetData();
//Check that writeline was called twice
consoleMock.Verify(c => c.WriteLine(It.IsAny<string>()), Times.Exactly(2));
//Check that writeline was called with you display message
consoleMock.Verify(c=>c.WriteLine(expectedDisplayMessage), Times.Once);
//check that Readline was called once
consoleMock.Verify(c=>c.ReadLine(),Times.Once);
//Check that writeline was called with your test string once
consoleMock.Verify(c=>c.WriteLine(readString), Times.Once);
}
}