Why is the class not accessible in unit test? - c#

I have created a unit test for a method in a class called game.cs. For some reason, when I reference the class, I am unable to create a new instance. How do I make this class accessible so I can test my code?
File Hierarchy and solution:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BowlingKataTDD;
namespace BowlingKataTDDTest
{
[TestClass]
public class BowlingKataTDDUnitTests
{
[TestMethod]
public void DoesGameExist()
{
//arrange
BowlingKataTDD.
}
}
}
BowlingKataTDD Project:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BowlingKataTDD
{
class Game
{
static void Main(string[] args)
{
}
}
}

The reason you do not see the classes is that they are non-public (internal by default).
There are two solutions to this:
If you would like to make your classes visible to outside users, make them public
If you would rather not publish your classes, use InternalsVisibleTo attribute.
To use the second solution, open AssemblyInfo.cs and add the following line:
[assembly: InternalsVisibleTo("BowlingKataTDDTest")]
BowlingKataTDDTest is the name of your assembly, as defined in the project file.

Make the class public, as well as any members of that class which need to be invoked externally (such as by a unit test):
public class Game
{
public static void Main(string[] args)
{
}
}

This is a common mistake with calling libraries with new projects, and I was able to resolve it. Often easy to forget to change the modifier to public from the project in Visual Studio, because by default a new project template creates the class though without it being set to public. When changing the Game class to public, am able to instantiate the Game object.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BowlingKataTDD;
namespace BowlingKataTDDTest
{
[TestClass]
public class BowlingKataTDDUnitTests
{
[TestMethod]
public void DoesGameExist()
{
//arrange
BowlingKataTDD.Game game = new BowlingKataTDD.Game();
}
}
}

Related

How to avoid having to write namespace before class C#

So I made a .dll which I added to my project everything works, but when I try to use any of the class from my .dll. I have to specificly use namespace.classname instead of being able to just say Classname even when I put at the top of my project
using namespace
using System;
using MyTestClassLibrary;
using System.IO;
using YangHandler;
namespace UsingMyclassdll
{
class Program
{
static void Main(string[] args)
{
YangHandler.YangHandler yangh = YangHandler.YangHandler.Parse("Rawtext");
Console.ReadKey();
}
}
}
At the line of using Yanghandler visual studio says
Using directive is unnecessary
Isn't this what using is exactly used for to use other namespaces?
YangHandler code
using System;
using System.IO;
namespace YangHandler
{
public class YangHandler
{
public string YangAsRawText { get; private set; }
public static YangHandler Parse(string YangAsRawText)
{
YangHandler handlerToReturn = new YangHandler();
handlerToReturn.YangAsRawText = YangAsRawText;
return handlerToReturn;
}
I know that it could be solved by using namespace aliases under the namespace "UsingMyclassdll" like
using YangHandler = YangHandler.YangHandler;
But isn't there a more normal solution?
Check this very interesting piece of documentation from Microsoft: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-namespaces
DO NOT use the same name for a namespace and a type in that namespace.
For example, do not use Debug as a namespace name and then also provide a class named Debug in the same namespace. Several compilers require such types to be fully qualified.
So your work around is basically defining the fully qualified name as the type and namespace are of the same name.
No work around for this. The compiler can't know if you mean the one or the other.

C# error while calling class

I learned basic and now I want to learn OOP in C#
I have this code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace uceni_cs
{
class Zdravic
{
public void pozdrav()
{
Console.WriteLine("Ahoj světe ! ");
}
}
}
But when I try to call it using this code
namespace uceni_cs
{
class Zdravic
{
public void pozdrav()
{
Console.WriteLine("Ahoj světe ! ");
}
}
Zdravic trida = new Zdravic();
}
In code Zdravic trida = new Zdravic();
is error. A namespace cannot directly contain members such as fields or methods.
What I am doing wrong ? I just want to call the class.
Thanks
In C# there is no such a thing global variable so you can't just create new instance of Zdravic type that does not belong to any class.
I suggest you to read General Structure of a C# Program, and c# Classes and Structs.
You need to create an entry point to your application and instantiate the class there.
class EntryPoint
{
static void Main()
{
Zdravic trida = new Zdravic();
trida.pozdrav();
}
}
Create your class object in main method and then use the class properties using that object.
Zdravic trida = new Zdravic();
in main method of you program/application.

Extension Methods with Custom Classes

I'm attempting to extend my custom classes and running into a problem where it cannot find the extension method.. I have and can extend any built in classes or even ones contained within DLL's. I don't know if this is a compilation error or if I'm doing something wrong. Threw together a small program for an example, won't compile..
Here's the extension:
namespace ExtensionMethodTesting.Extension
{
public static class Extension
{
public static void DoSomething(this ExtensionMethodTesting.Blah.CustomClass r)
{
}
}
}
Here's the Custom Class:
namespace ExtensionMethodTesting.Blah
{
public class CustomClass
{
public static void DoNothing()
{
}
}
}
Here's the code calling it:
using ExtensionMethodTesting.Blah;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExtensionMethodTesting.Extension;
namespace ExtensionMethodTesting
{
class Program
{
static void Main(string[] args)
{
CustomClass.DoNothing();
CustomClass.DoSomething();
}
}
}
I must be missing something... Anyways the exact error just for clarification is:
Error 1 'ExtensionMethodTesting.Blah.CustomClass' does not contain a definition for 'DoSomething' c:\users\damon\documents\visual studio 2013\Projects\ExtensionMethodTesting\ExtensionMethodTesting\Program.cs 16 25 ExtensionMethodTesting
Extension methods require an instance of an object. You'll have to new up a CustomClass to use it.
var custom = new CustomClass();
custom.DoSomething();
See this answer as to why that is.
You need to instantiate an object of the CustomClass to use its extension method.
CustomClass obj = new CustomClass();
obj.DoSomething();

Why do extension methods not work with namespace aliasing?

This may be an ignorant question, but I'm unsure why I can not use namespace aliasing and extension methods together.
The following example works just fine:
Program.cs
using System;
using ExtensionMethodTest.Domain;
namespace ExtensionMethodTest
{
class Program
{
static void Main(string[] args)
{
var m = new Domain.MyClass();
var result = m.UpperCaseName();
}
}
}
MyClass.cs
using System;
namespace ExtensionMethodTest.Domain
{
public class MyClass
{
public string Name { get; set; }
}
}
MyClassExtensions.cs
using System;
namespace ExtensionMethodTest.Domain
{
public static class MyClassExtensions
{
public static string UpperCaseName (this MyClass myClass)
{
return myClass.Name.ToUpper();
}
}
}
However, when I alias domain as follows in Program.cs:
using Domain = ExtensionMethodTest.Domain;
The extension method no longer works..
This can be rather frustrating when I'm dealing with converting various domain objects to contract objects (let's say I have 4 domain assemblies and 4 contract assemblies) for use in a web service. Using aliasing would be very handy as I could alias as follows and continue to use the various extension methods (such as ToContract, etc.):
using BillingContracts = Namespace.Billing.Contracts;
using IssuingContracts = Namespace.Issuing.Contracts;
etc...
I look forward to the answer.. I'm sure it's straight forward, but I, for the life of me, can't figure out why it doesn't work.
Thanks!
Make sure to still add a non-aliased using statement:
Program.cs
using System;
using ExtensionMethodTest.Domain; //DON'T FORGET A NON-ALIASED USING
using MyDomain = ExtensionMethodTest.Domain;
namespace ExtensionMethodTest
{
class Program
{
static void Main(string[] args)
{
var m = new MyDomain.MyClass();
var result = m.UpperCaseName();
}
}
}
MyClass.cs
using System;
namespace ExtensionMethodTest.Domain
{
public class MyClass
{
public string Name { get; set; }
}
}
MyClassExtensions.cs
using System;
namespace ExtensionMethodTest.Domain
{
public static class MyClassExtensions
{
public static string UpperCaseName (this MyClass myClass)
{
return myClass.Name.ToUpper();
}
}
}
I also love to use namespace aliasing but its not working in case of Extension methods. So one thing that i did is, I changed the namespace of extension class to same namespace that my main project has (although my extension class resides in sub folder of main project).
Suppose I have a project myFirstProj which surely has namespace myFirstProj for root classes. My extension class is present in myFirstProj/Common/myExtensionClass with contains namespace myFirstProj.Common { //myExtensionClass }.
So now what I did is, I changed the namespace of myExtensionClass from namespace myFirstProj.Common{ //myExtensionClass } to namespace myFirstProj{ //myExtensionClass } .
Now i can use my extension methods in my whole project myFirstProj event without specifying using statement for my extension class.
I know this isn't a standard way to that but I haven't found any other workaround for it expect this one because for my Project there is a requirement to go with namespace aliasing for project namespaces.

How do I add common C# code to a Visual C# 2008 Express project/solution?

(I still feel like a complete newbie in MS Visual environments... so please bear with!)
I'm using Microsoft Visual C# 2008 Express Edition.
I have a project and in that project are two different forms. The .cs file for each form starts out:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyNameSpace
{
public partial class MyFormName : Form
{
...
(...and the second is "MyFormName2" but no differences besides that)
I want to write a function that I know both forms are going to need to access. I right-clicked on my project, selected "Add", selected "New Item" then selected "Code File" and named my file "Common.cs" and it gave me a completely blank file that's in my project.
How do I set this up...? I thought I should do the following...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MyNameSpace
{
}
...but then when I try to add a function like:
public void mytestfunc() {
}
within that namespace I get the following error:
"Expected class, delegate, enum, interface, or struct"
How do I set things up so I can have "mytestfunc" be available to both MyFormName and MyFormName2?
Thanks!
-Adeena
UPDATE:
Understand (now) that everything must be in a class, but then I don't understand how to really use it. Does that mean I have to create an object? This common function happens to just be some math...
so now if I have this:
namespace MyNameSpace
{
public class MyCommonClass
{
public void testFunc()
{
MessageBox.Show("Hee hee!");
return;
}
}
}
...how do I call testFunc from my Form? Must I do the following:
MyCommonClass temp = new MyCommonClass;
temp.testFunc();
or is there another way to call testFunc?
If you do something like:
namespace MyNameSpace
{
public class myclass
{
public myMethod()
{
// Code
}
}
}
You will be able to instantiate and access it. If you change it to:
namespace MyNameSpace
{
public class myclass
{
public static myMethod()
{
// Code
}
}
}
You will be able to call myClass.myMethod without instantiating a new myClass.
The short answer is that everything needs to be inside a class; I'd suggest you sit down with a basic tutorial to help you get to grips with the basics...
Code need to be inside classes.
It would look something like this:
using System;
namespace MyNameSpace
{
public class CommonHelper
{
public string FormatMyData(object obj)
{
//do something
return String.Empty;
}
}
}
If the function you call is not related to the forms, make it static
namespace myns
{
public static class myhelper
{
public static void DoSomething()
{
}
}
}
and call the method using myhelper.DoSomething();
If the function you want to call is somehow form-related, e.g. common functionality across multiple forms, derive a class from Form (does not need a visual form) and make it base class of the visual forms:
namespace myns
{
public class MyFormBase : Form
{
protected void DoSomethingWithTheForm()
{
}
}
}
and in your form's .cs:
namespace myns
{
public partial class MyFormName : MyFormBase
{
}
}

Categories