Adding a command line input for testing a method in C# - c#

I am writing a program in a C# Console Application and within some of the methods I have Console.ReadLine() and Console.WriteLine(). I want to know how to give the input within a Test Case.
Example:
Console.WriteLine("Enter account number: ");
accountNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter name: ");
cStringName = Convert.ToString(Console.ReadLine());
name = cStringName;
Console.WriteLine("Enter balance: ");
balance = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter Date: ");
dateCreated = Convert.ToString(Console.ReadLine());
So basically the method returns a bool saying if an account was created or not. In my test case I want to be able to call this method but in order for it to execute I need to set accountNumber, name, balance, and date. Is there some sort of way of doing this? Or is the best way just to add parameter to the method(which i prefer not to do)?

Rewrite the method so that it takes a couple of Stream as parameters. Then when you call it in the real program, send in Console.Out and Console.In as parameters. When calling from your test case, send in some memory streams instead.
When writing this kind of methods and you want to test them, they should not depend directly on the console, but rather on an abstract stream. Then you use dependency injection (e.g. passing in the streams as parameters) to be able to substitute the console for a memory stream when testing.

Related

C# - Multiple Errors

After writing my second program in C#, I receive an error:
Error in Compiler
The error might pertain to the library
or it might be on the Conversion
or the namespace
using System;
namespace MagpantayUserInfoProg {
class UserInfo {
static void Main() {
string name, gender; // Variables for storing words
int contact, age; // Variables for storing integers
Console.Write("Name: "); // Let the user input his name
name = Console.ReadLine(); // System reads data
Console.Write("Gender: "); // Let the user input his gender
gender = Console.ReadLine();// System reads data
Console.Write("Age: "); // Let the user input his age
age = Int32.Parse(Console.ReadLine()); // System reads data
Console.Write("Mobile Number: "); // Let the user input his contact number
contact = Int32.Parse(Console.ReadLine()); // System reads data
// Display Output
Console.Write("Name: {0}\n", name);
Console.Write("Gender: {0}\n", gender);
Console.Write("Age: {0}\n", age);
Console.Write("Mobile Number: {0}\n", contact);
Console.ReadLine();
}
}
}
mobile number too large for int
https://learn.microsoft.com/tr-tr/dotnet/csharp/language-reference/builtin-types/integral-numeric-types
check int range
also use string for storing mobile number
Let's dissect the error message:
Value was either too large or too small for an Int32
So, that tells us the problem is somewhere where we're creating an Int32, and Int32.Parse(Console.ReadLine()); fits the bill, not only are we creating an Int32 here, but this is also the point in the program where the error (exception) is encountered (thrown). But why? Well, because computers don't have infinite memory, so a while ago people (read: software developers) decided on a bunch of standards on how to represent data inside a computer, and those standards contain limits, and the limit for an Int32 (which by the way is the standard int in C#) is no smaller than -2,147,483,648 and no larger than 2,147,483,647 (source), but your phone number is 09,563,977,528, larger than the maximum allowed, and hence the error.
So what do we do now? Well, we could use a larger integral type, like long and Convert.ToInt64, but that's just a band aid solution, instead we should use a string (or a more specialized data structure*). Think about it, is a phone number really just a number? No, it isn't, for one the phone numbers 09563977528 and 9563977528 aren't the same right? But if they're were regular old numbers, they would be, 02 and 2 are the exact same number. Additionally, it doesn't really make sense to use arithmetic operations on phone numbers, there's never a need to multiply or subtract or add or whatever 2 phone numbers together. So for those reasons, I'd suggest we just leave phone numbers as strings.
* A good exercise for when you learn about classes and structs would be to implement a custom class representing a phone number
As others have pointed out, the number is too large to be stored as an Int (Int32) value which can handle any number between
-2,147,483,648 and 2,147,483,647
Generally, you should not store a phone number as a numeric value anyway, because many phone numbers include a leading zero which is critical but cannot be stored if you store the value as a number. But as not all phone numbers do include a leading zero, then you can't assume that there always is one.
So then you need to store this as a string value instead, and then include some validation to ensure that only numbers are entered.
There are many different ways to do this, so you can investigate further to see which suits you, but as an example you can try this, which will scan the string to check that each character is a digit.
Console.Write("Mobile Number: "); // Let the user input his contact number
contact = Console.ReadLine(); // System reads data
if (contact.All(char.IsDigit))
{
// String only contains numbers
}
else
{
//Handle error here
}
Edit:
Of course this solution only allows digit. So if the user wishes to prefix a country code using a '+', then this will not be supported. So then you need to change the solution to support this.
Also, FYI: You don't have a compiler error, you have a runtime exception.

Trying to fix reading from file C#

I have made a small console application, works fine other than when I enter a pin, will include some code soon, I can enter part of it and it will still log me in, I do not want it to do this, I need the pin to be exact to log in.
Full code can be accessed here: https://pastebin.com/ARX1MqLc
Console.WriteLine("Please insert your credit card by pressing 'Enter'.");
Console.ReadKey();
Console.Write("Please enter your 4-digit PIN: ");
pin = Console.ReadLine();
bool pinVerif = File.ReadAllText("C:/Users/ryanj/OneDrive/Documents/Random code/myApp/pin.txt").Contains(pin);
if(pinVerif == true)
{
verified();
}
else
{
Console.WriteLine("Sorry your PIN was incorrect, please try again or exit the program.");
menu();
}
I did create a file that is called pin.txt, so you will need to create that and put anything in it, but I honestly don't know whats wrong with it.
You need an exact match in this case:
string pinContent = File.ReadAllText("C:/Users/ryanj/OneDrive/Documents/Random code/myApp/pin.txt");
bool pinVerif = (pin == pinContent);
That's because of the way contains works. It compares the string you entered with the whole string and checks to see if that part is in there.
Their are tons of ways to solve this. The easiest is to check if the length of your pin is 4.
if(pinVerif && pin.length==4)
or you could do something more complicated and use i.e. json to store the pins in seperate object.

Asking the user the same question more than once in C#

Starting my Intro To Programming class and we'll be using C# throughout it. I'm currently writing a practice program to get familiar with C# that asks the user for their name and age and then reads it out to them and asks if it is correct. I want to make it so that if the user wants to change their inputted data for any reason then they can press the "n" key for "no that's not right" and re enter their data. However, I want to re-ask them the questions for their age and name(separately) without having to re-type the code block with the Console.WriteLines and if...else block. I did some research and found that:
the "go-to" statement was made by the devil himself and it's essentially the programming equivalent of a hate crime if I use it
making a new method (and subsequently calling that method in my code) with the block of code asking the question seems to be the way to go about it.
My problem is that while I've (hopefully) figured out that's what I need to do, I can't seem to figure out how exactly to either implement that method nor call it correctly later on.
here is the method I'm trying to create that I want to hold an "if...else" statement asking if the info is correct, incorrect, or re-ask the question if the enter something other than "y" or "n":
public void Question()
{
Console.Write("Could I get your name? (Press enter when you are done) ");
string user_name = Console.ReadLine();
Console.Clear();
Console.Write("Awesome! Now if you could just enter your age: ");
string user_age = Console.ReadLine();
Console.Clear();
Console.WriteLine("So according to the information I have on file here... you are " + user_name + " and you're " + user_age + " years old....");
}
This isn't homework so I don't mind specific pieces of code so I can see how it works and tinker with it to learn :)
Good work on doing some research on your own, and a fairly decent question. And you're on the right track.
So let's first focus on asking the question part. If you look at your Question() method, you can see that you're sort of doing the same thing repeatedly inside it. Yes you're asking different questions, but essentially you're doing three things:
Ask a question.
Get the answer.
Clear the Console.
So, maybe you can put those three things into one method, and the only thing that's variable here is the question, so you can pass the question as a parameter.
static string AskQuestion(string question)
{
Console.Write(question);
var ans = Console.ReadLine();
Console.Clear();
return ans;
}
Alright, a bit better.
Now, how do we repeatedly ask the user a question until we get a satisfactory answer? Loops are a good solution, and particularly either while or do-while which doesn't iterate a set number of times but rather until a condition is fulfilled. I personally like to use do-while in a situation like this.
So what do we have to do there now? Let's break it down. We will write a function, and inside a loop we want to:
- Ask a question and get the answer. Good thing we have a method that does just that.
- Show the user the answer he/she entered.
- Ask the user to confirm if it's good.
- If yes, terminate the loop, and return the answer.
- If not, ask the question again.
Something that looks like this:
static string GetSatisfactoryAnswer(string question)
{
var ans = string.Empty;
bool goodAns = false;
do
{
ans = AskQuestion(question);
Console.WriteLine("You entered {0}. Is that correct?", ans);
var confirm = Console.ReadLine();
if (confirm.ToLower() == "y")
goodAns = true;
} while (!goodAns);
return ans;
}
Now you can call them like this:
static void Main(string[] args)
{
var name = GetSatisfactoryAnswer("Could I get your name? (Press enter when you are done) ");
var age = GetSatisfactoryAnswer("Awesome! Now if you could just enter your age: ");
Console.WriteLine();
Console.WriteLine("Name : {0}", name);
Console.WriteLine("Age : {0}", age);
Console.ReadLine();
}
NOTES
This is only to give you a rough idea, you'll need to do a lot of error handling. Such as, what if the user enters anything other than Y/N for the confirmation?
It's always a good idea to actually get the age as an integer. So use int.TryParse() to convert the string input into an int and then do something about it if a non-numerical value was entered.
In your example, you get both Name and Age at once, then asks use to confirm them later. In my opinion, it's best to finish one thing and start another. In other words, make sure your got a satisfactory answer to Name, then move onto Age, etc. My answer is designed that way.
Hope this helps. Good luck!

Is this behavior due to possible async?

Salutations,
I am fairly new to C#, I feel comfortable with Java, and thus I feel decently comfortable with C# (massive fan of its LINQ and SQL syntax). Anywho, I am however a total novice to asynchronous calls, and I was wondering if the following behavior is related to this.
So in my code I have the following:
string sentence;
Console.WriteLine("Enter your sentence: {0}", sentence = Console.ReadLine());
Console.WriteLine("Sentence is: {0}", sentence);
Console.ReadKey();
It is very simple, I was just trying to see if I could insert the reading of the input within the same prompt that asks for it. However, what I notice is that the code runs, but it is a blank screen, I can type my input and then it would display what I typed, and wait for a key click in order to close the CMD window.
What I was wondering is the following: Is this a sort of async behavior -- if not, what is it then? And if so, is it possible to have the ReadLine() within the same Console.WriteLine() or do I have to have them as two separate lines as one would normally do?
There is nothing about asynchronous here.
The first Console.WriteLine requires its parameter(s) to get ready before its own execution. In other words, Console.ReadLine has to execute before the first Console.WriteLine. That is where the blank screen come from.
Just write as
Console.WriteLine("Enter your sentence: ");
sentence = Console.ReadLine()
Console.WriteLine("Sentence is: {0}", sentence);
or in "the same line"
Console.WriteLine("Enter your sentence: ");
Console.WriteLine("Sentence is: {0}", Console.ReadLine());
Synchronous and Asynchronous is not the concern here, just syntax error try
Console.WriteLine("Enter your sentence: ");
Console.WriteLine("Sentence is: {0}", Console.ReadLine());

How do I receive and store data input in C#?

Basically I'm still in the starting phase, and I know how to use Console.WriteLine, but I have no idea on how to have it read input from the user.
For example, I'd want a user to be able to type in a pair of numbers, then return the result.
My goal is a program that receives input , then combines them and returns the average.
This is all in Visual C# Express 2008
string input = Console.ReadLine();
that will return you a string of the user's input. Check out MSDN for documentation on the Console class. Also look at the Convert class.
int num = Convert.ToInt32(input);
Good luck new coder.
First create a variable to store the user input, like this:
int variablenameofyourchoice = 0;
Then take input like this and store it in your variable name:
variablenameofyourchoice = int.parse(Console.ReadLine())
Then do whatever you want with that variable. If you want two numbers do this twice.
This is a very general topic with a lot of answers, but Console.ReadLine is one counterpart of Console.WriteLine. It reads a line of text from standard in.
Have a look at Console.ReadLine() or Console.Read() in the MSDN Documentation

Categories