Creating Unit Tests in VS only allowed in Public Classes? - c#

I am trying to clarify this notification message when trying to create a unit test for my method. The message clearly states that creating a unit test is only supported on a NON-Test project and within a public class OR a public method. I clearly have a public method but the class isn't. So is this just an incorrectly typed error message? Does it actually mean that you need to have both a public class and method?
Note: It works when I try this in a public class, just testing the notification.
Picture of notification message:

To test your class/method, you have to create another project - Testing project. Look at this as it has been another application that uses your classes.
So for example you have 3 projects (for sake of simplicity):
Domain - project with models and domain services
Console application - application that uses domain project
Test... let's say "Testing application" that tests Domain project.
So it points that class that you want to test MUST be available from test project. So it has to be public. You can also use attribute InternalsVisibleTo to make this class available for test project.

Your unit test project must be able to see (public visibility) the method you want to test in order to call it and execute it.
Here is a sample on a WinForm application:
You can clone the whole solution here:
Visual Studio solution on GitHub
Note that you can unit test private methods but it is not a good practice:
Solution downloadable here:
visual Studio solution on GitHub

Related

Initialize ASP.NET Core Web API from another project

I have an application that is structured as follows:
Class A with certain methods exposed
Class B that basically acts as the command line interface, calling the exposed methods of an instance of class A
Class B's constructor takes an instance of class A as an argument and works with that instance from then on.
public class B
{
private A ainstance
public B(A ainstance)
{
this.ainstance = ainstance;
}
}
class Program
{
void Main()
{
var x = new A();
var y = new B(x);
}
}
This structure has worked fine so far. Now however I need to implement an API so that the same operations can be performed on A from a web interface. I chose to use .NET Core for the API, and have implemented most of it. My plan was to add a reference for the API project to the original project and then call the startup method from my Main(), once gain passing the instance of class A as an argument. This doesn't work. Visual Studio refuses to add the reference for reasons unknown.
Is there a way to implement my original idea? If not then ideas for an alternative structure would be greatly appreciated.
As it turns out, all I needed to do to get it to work was to use create .NET Core Console Application project instead of a normal Windows one.
When I was trying with a normal Console Application project, Visual Studio gave a misleading error: "A reference to [API project name] could not be added. An assembly must have a 'dll' or 'exe' extension in order to be referenced", which led to my confusion. I discovered the actual problem when I tried doing the reverse (referencing the console project from the API one), and VS showed the framework incompatibility.
What I understood that your Class A and Class B will remain same except the Class 'Program' logic in your example will go in Asp.NET page.
I think you just needed to create a Library project and put the old logic withing this ie: Class A and Class B, compile it, reference this library output in your Asp.Net application, you should be good to go.

TDD solution architecture best practice

How will be the solution architecture of TDD project. I mean how should I design a test project?
I have to write a test project for an already existing developed MVC project. I will enhance some of the new feature. This will be the first time for this project to develop new feature using TDD approach. Is there any convention that I should follow?
Should I create a separate test application, then write some test class, methods. Then implement the actual functionality in the same test project or in the original project where new feature will be implemented.
Another thing I need to know, is there any specific convention for naming classes,methods, variable? I will use MS test and for mocking MOQ.
Create new Test solution with one Test project (suggested name for test project <OriginalProject>.Tests - thanks to #ReneA)
Add your original project as Existing project to the test solution
Add reference of original project to the test project
Create same folder/namespace structure as in original project. This will help navigating in both projects - thanks to #ReneA
Create new Test class
Add new test method where you will call a method from original project and assert results
Do not waste time with naming in the beginning. Start writing tests, run them. After few tests you will be able to find out by yourself what naming conventions is more suitable for your project.

Unit test C# console application ('using' not working)

I am working with Visual Studio 2015. I have created a new C# console application and a new Unit Test Project. I want to connect the two of them, to be able to do unit tests. I have added a reference to the console application in the Unit Test Project. But when I try to add the using statement, it does not pop up in Intelli-Sense.
With a class library instead of a console application, this worked fine. Why doesn't this work, and how do I get it to work?
Thanks in advance
You need to create new public class in console application, where you will write your functionality, after that you need to create an instance of this class in the unit test and test the functionality.
Class Programm its an entry point which parses the arguments, so you dont need to have there any logic and also you dont need to test it.
The fix is a combination of all your answers/comments.
IntelliSense does not show the Console App. I don't know why, maybe because there is no public class yet. I can type it manually. It won't work calling main or the main class (called 'Program'). But if I create a public class with a constructor, I can call it from the unit test.
So, basically, my template works, and can now be used to build my future TDD projects on.
Thanks to you all!

Is it possible to execute an arbitrary class in C# with a Main method, similar to that in Java?

I've recently had to migrate to the C# world. Coming from the Java land, I could add a public static void main(String[] args) method to any class and select to run that class from Eclipse/Netbeans for any code/logic that I wanted to quickly test.
Is there an equivalent of the same capability in C#.Net/Visual Studio? I've tried doing that and the best I can do is to execute it from the command prompt via csc.exe. However, for some reason, it complains about not finding the relevant DLLs - it seems to expect to run that class in complete isolation without any dependency on "external code" (i.e., code residing in that VS project/solution where the class resides).
Reason for this capability: All project files are marked as class libraries and sometimes I just wish to check if a particular set of methods/data/logic will work as expected with the current code base. In Java, I'd quickly write it in the main method and execute that class to see how it goes prior to committing it to version control. However, there seems to be no easy way to trigger the execution of "my class" with all dependencies correctly handled by csc.exe
Current Solution: Add this testing code to the unit test project and select to execute that particular "test" so as to check if the idea seems to work fine (it may fire DB calls or webservice class etc., and not be purely a logical flow of computation). This seems to work fine and is my current way of doing things. I was wondering if the Main method was even possible/recommended.
Question: Is this even possible with C#/VS or not recommended?
Update: I can't add a console project just to achieve this since the addition of projects is tightly controlled by the source control team. Hence the question of the Main method 'hack' for quick and dirty checks/tests.
Your project type needs to be Console Application for it to "recognize" a Program.Main method, not Class Library. The intent is for a Class Library to be an encapsulated grouping of functionality that can only be accessed by a project that is set up to allow for user input. Those can be a Console Application, Web project (MVC/API), or Desktop (WPF).
If you just want to execute a test against the code within a Class Library project, you can also create a Unit Test project, add a reference and execute very explicit tests against the functionality you're looking to achieve.
You can find out the differences between the different project types by examining the .csproj files in your favorite text editor.
In Visual Studio go New->Project then select Console Application (in Windows\Classic Desktop in VS2015). This gives you a basic console application with...
static void Main(string[] args)
{
}
setup and ready to go. However for simply trying out code you may find this cumbersome (creating a new project and folder just to test code) and for testing code (that doesn't rely on existing libraries) you could use something like .NET Fiddle...
https://dotnetfiddle.net/
Where you can quickly create and test code there and run it via the browser.

Win10 UWP, Prism/Unity and Unit Tests plus Class Libraries, silent failure

Basic layout is currently a simple app. Nothing fancy, I've got Views in the App.Views namespace and my ViewModels in the App.ViewModels namespace. The ViewModels are autowired to the Views through the XAML directive:
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
So, basically, this works. Then I wanted to leverage Unity's IoC / DependencyInjection for some unit tests.
The usual way would be to simply add a Windows 10 Unit Test App to the existing app and reference the latter in the Unit Test App.
This will crash upon executing the unit tests because it seems that you may not derive the App class from anything other but Application.
I.e. this works:
public sealed partial class App : Application
This does not:
public sealed partial class App : PrismUnityApplication
It's probably also not Prism's fault and something Microsoft has to fix on their end.
Now, the proposed workaround is to simply put whatever you want to unit test into a class library and reference this library from the unit test app. This works for unit testing. It also works for the Models.
My naive approach does not work, however, for the ViewModels. The ViewModel classes are still found under the App.ViewModels namespace, as before, just that they're now in a Class Library. I can access them programmatically in the main app just fine. But upon running the program, the AutoWiring silently fails without an error.
Even when I do something like this, it still does not work:
ViewModelLocationProvider.Register(typeof(MainPage).ToString(), () => new ViewModels.MainPageViewModel());
I'm not that experienced with the technologies involved yet so without an actual error I'm a bit at a loss.
edit: Just to add to the mystery - this code does work, regardless of whether the ViewModel resides in the main app or the class library:
var x = Container.Resolve(typeof(ExamplePageViewModel)) as ExamplePageViewModel;
You are correct, this is a limitation of UWP application testability in general. The testability of UWP apps is imperfect right now. In order to fix the first issue, you need to add the BindableAttribute to your application class:
[Bindable]
sealed partial class App : PrismUnityApplication
{
}
As far as pulling your Views/ViewModels out into separate assemblies, this issue is due to how UWP handles loading types form separate assemblies. None the less, this shouldn't stop you from testing your ViewModels. You can use a regular class library to test your ViewModel logic. You will mock your dependencies. You shouldn't be creating instances of your Views to test your ViewModels. So the ViewModelLocator becomes a non-issue.
We got the same issue as you, test silently failing.
when we looked at the Test output window we saw this:
App activation failed.
Failed to initialize client proxy: could not connect to test process.
Inside our [UnitTestApp], which inherits [PrismUnityApplication], we override [ConfigureContainer] method, and setup mocks on the container, instead of setting up real classes, i.e.
UnitTestApp.Current.Container.RegisterInstance(myMock.Object, new ContainerControlledLifetimeManager());
You may also have the Container setup in each test class' constructor
This way we got our test running without a silent failure.
It seemed that the silent failure was due to the container of the actual App class being called in the context of the UnitTestApp class - but I cannot confirm 100%

Categories

Resources