How to test Wep API client without running application - c#

I have some api controllers and generated a swagger client with tests for them and filled it out. Here an example of filled test class:
[TestFixture]
public class CategoriesApiTests
{
private CategoriesApi _instance;
[SetUp]
public void Init()
{
_instance = new CategoriesApi("http://localhost:5000/");
}
[Test]
public void InstanceTest()
{
Assert.IsInstanceOf<CategoriesApi>(_instance, "instance is a CategoriesApi");
}
}
But my tests only pass if I run my application.
How can I emulate running an application for testing?

What you may want to do is to separate all business logic into a separate DLL and then use unit testing.

Related

Best practice for unit test cases

I am using the xUnit.net test framework and in each unit test I have certain steps which I am doing in each case. I would like to know if there is a way I call this method once before my unit case starts and also call when all unit test cases has been executed.
For example: In the scenario below I have two unit cases and in each case I am creating a local DB, populating it with data and then running my test and once it is done I am calling method to delete the DB. This I am doing in each test case. Instead of multiple creation I would like to create once and populate once and then delete db once all test case has been executed. It is important for me to delete what I have created as the test cases has certain cases which will fail if Database is not created when the tests are executed.
[Fact]
public void UnitCase1()
{
CreateDb();
UploadData();
...//My set of operation to test this case
...//Assert
DeleteDb()
}
[Fact]
public void UnitCase2()
{
CreateDb();
UploadData();
...//My set of operation to test this case
...//Assert
DeleteDb()
}
Editing after Answer from Eric:(I tried but its not working)
public class CosmosDataFixture : IDisposable
{
public static readonly string CosmosEndpoint = "https://localhost:8081";
public static readonly string EmulatorKey = "Mykey";
public static readonly string DatabaseId = "Databasename";
public static readonly string RecordingCollection = "collectionName";
string Root = Directory.GetParent( Directory.GetCurrentDirectory() ).Parent.Parent.FullName;
DocumentClient client = null;
public void ReadAllData( DocumentClient client )
{
//reading document code
}
public void ReadConfigAsync()
{
client = new DocumentClient( new Uri( CosmosEndpoint ), EmulatorKey,
new ConnectionPolicy
{
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp
} );
}
public void CreateDatabase()
{// create db code
}
private void DeleteDatabase()
{
// delete db code
}
public CosmosDataFixture()
{
ReadConfigAsync();
CreateDatabase();
ReadAllData( client );
}
public void Dispose()
{
DeleteDatabase();
}
}
public class CosmosDataTests : IClassFixture<CosmosDataFixture>
{
CosmosDataFixture fixture;
public CosmosDataTests( CosmosDataFixture fixture )
{
this.fixture = fixture;
}
[Fact]
public async Task CheckDatabaseandCollectionCreation()
{
List<string> collectionName = new List<string>();
var uri = UriFactory.CreateDatabaseUri(DatabaseId);// don't get DatabaseId or client says does not exist in current context
var collections = await client.ReadDocumentCollectionFeedAsync( uri );
foreach( var collection in collections )
{
collectionName.Add( collection.Id);
}
}
That's what [SetUp] and [TearDown] are for in NUnit. They are run right before and right after each test case, respectively. In xUnit you would usually implement a default constructor and IDisposable.
For example:
public TestClass()
{
CreateDb();
UploadData();
}
public void Dispose()
{
DeleteDb()
}
[Fact]
public void UnitCase1()
{
...//My set of operation to test this case
...//Assert
}
[Fact]
public void UnitCase2()
{
...//My set of operation to test this case
...//Assert
}
As other people have pointed out, such tests are in mainstream parlance not unit tests, but rather integration tests. xUnit.net is a fine framework for those kinds of tests, though, so apart from the semantic distinction, it makes little technical difference.
Apart from setting up the database in the test class' constructor and tearing it down in Dispose, as outlined by Eric Schaefer, you can also use xUnit.net's BeforeAfterTestAttribute. You'll then override Before to set up the database, and override After to tear it down:
public class UseDatabaseAttribute : BeforeAfterTestAttribute
{
public override void Before(MethodInfo methodUnderTest)
{
CreateDb();
UploadData();
base.Before(methodUnderTest);
}
public override void After(MethodInfo methodUnderTest)
{
base.After(methodUnderTest);
DeleteDb();
}
}
You can then annotate either each test method, or the entire test class with the attribute. I usually just annotate the class:
[UseDatabase]
public class DbTests
{
// Tests go here...
}
Since tests that use a database interact with a shared resource (the database), they can't easily run in parallel. By default, xUnit.net runs tests in parallel, so you may want to disable that. You can do it by adding an xunit.runner.json file:
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"parallelizeTestCollections": false
}
Finally, at least if you're using SQL Server, connection pooling will prevent you from deleting the database. You can either turn off connection pooling for your tests, or forcibly close other connections before teardown.
In my experience in Testing, I see 2 points here:
1-If you are checking that the data from the DB to another point in the program is being transmited correctly, that is Integration Testing, and it should be out of scope in the Unit Testing Plan, make sure that the responsabilities of a Unit Tester are clear where you work as there are some companies which avoid Integration Testing levels by assuming that if Functional Testing is 'OK', integrations should be too.
2- You mention at the end
It is important for me to delete what I have created as the test cases has certain cases which will fail if Database is not created when the tests are executed
but
I would like to create once and populate once and then delete db once all test case has been executed.
If I understand correctly, you need to do it for each Test Case as not all test cases are checking the same scenario, so it looks like those statements are the real problem here.
To answer your question, as it seems like you want to automate the process with minimum maintenance for the next releases, and I also know how the work environment tend to corner you to do some stuff that shouldn't be, I could think of a Preconditions Function and a Postcondition one, where you do it once and that's it.
If that is not possible for whatever reason, try to create another Test Case at the beginning (like Test Case 0) where you create and populate the DB (if apply, or separate it if needed) and another one at the end where you delete it.
I'm not familiar with the framework you are using, but I have a lot of experience in Testing, opening test levels and automating tasks, and hope that my answer could be of some help.

Is there a way to send a value from a unit test to another unit test?

I have a function which calculates some stuff and inputs it into a DB. This setup is important for all unit tests because they need some data to work on.
Sometimes i need to "flush" the DB, so all the unit tests point to the wrong ID.
Normally i just run the setup first and then change all the unit tests but this is taking to long tbh. Is there a way to automate this?
I would like to pass the generated ID into other unit tests.
So the idea was something like this:
[SetupFixture]
public class{
[Test]
public void SetupDB(){
setup();
//now marking the result somehow so other tests can pick the result up
return ID; //<--
}
}
public class OtherTests{
[Test]
[Get_ID_From_SetupDB]
public void testBaseOnID(int ID){
//we do stuff now with ID
}
}
PS: i have no problem switching the testing framework if you know a framework which can do this
Tests should be independent and you should generally never pass values between tests.
What you can do in your case, if all the tests are in the same class, is to have a variable in your class to hold the id and some global setup function that sets everything up and sets the variable to the correct id. In NUnit there is the [OneTimeSetUp] atribute for that.
[TestFixture]
public class MyTests
{
private int _testId;
[OneTimeSetUp]
public void SetItUp()
{
...
_testId = whatever;
}
[Test]
public void TestOne()
{
var whatever = _testId;
...
}
}

How to generate tests based on data in nunit framework using C#

So i have this code:
[TestFixture]
[Category("MyTestSet")]
public class MyTests
{
[Test]
public void TestCase12()
{
ExecuteTestCase(12);
}
[Test]
public void TestCase13()
{
ExecuteTestCase(13);
}
[Test]
public void TestCase14()
{
ExecuteTestCase(14);
}
}
The ExecuteTestCase gets test parameters from my web server and executes the test case with these settings.
Each time i add a new test case parameters on my web server i need to add a new test in my C# code and pass the ID of test case parameters i have in my web server database and compile my code.
Is there any way to do it automatically? Like say, C# gets from my server ID's of all test case parameters and creates tests for them on the fly?
What is important, test cases change frequently. I was thinking about running all test cases in one test case on a loop, but than i'd be unable to run my test cases separately for example in Nunit IDE.
So my question is: how to run multiple test cases depending on data i receive on run time.
You can use TestCaseSourceattribute in order to get parameters from web service and have your test cases auto generated
[TestFixture]
[Category("MyTestSet")]
public class MyTests
{
[Test, TestCaseSource(nameof(GetTestParameters))]
public void TestCase(int parameter)
{
ExecuteTestCase(parameter);
}
static int[] GetTestParameters()
{
//call web service and get parameters
return new[] { 1, 2, 3 };
}
}
documentation

Shim/fake object using external application

i've got class as below and i need to test RunMethod. Problem is, that ExternalClass needs some application run on server side (app providing external dll's). My dev environment has that app but my dev environment for test hasn't. My question is, how to shim/fake that ExternalClass in UnitTests to not check if app exist (test always faild in env without that external app)? This class is not important in tests but run automatically if i execute RunMethod.
public class MyExampleClass : ISomeInterface
{
private static ExternalClass = new ExternalClass(string someParam);
public object RunMethod()
{
/* Actuall code hear, doesn't matter */
/* few unimportant (from the view point of tester) operation in ExternalClass (object loggin etc.) */
return someVar;
}
}
MsFakes generate a property named AllInstances to the shim class, through this property you can override the behavior of any instance method:
[TestMethod]
public void TestMethod1()
{
using (ShimsContext.Create())
{
ShimExternalClass.AllInstances.ToString01 = () =>
{
return String.Empty();
};
Assert.IsNull(new ExternalClass().ToString());
}
}

Mocking a WCF client, with a parameterised constructor for .net component called from COM

I'm struggling to find a way forward here.
I have a VB6 screen, which i need to call a .Net 'adapter' component, which calls out to a WCF service.
The WCF service is under windows authentication as i want to detect the windows logon of the user calling the functionality.
The service reference is in the .Net adapter. To get this to work i have had to add detail to a binding, specifying the security, which all works fine in the real world.
My problem is unit testing this, and trying to mock the call to the WCFServiceClient. Because i am using a parametrised constructor, Moq will not mock it. So i believe that my mock is therefore not being used, and a real call is going through to the WCF layer when i run my unit test (it is, i put a break point in the wcf service running locally in my solution).
To simplify my code i've pasted a BasicHttpBinding in, as the problem isnt the security, its how do i recode the function so i can mock the call, or can i do something else allowing me to mock the call?
In the .Net adapter, in the function i am calling i have the following code
using (var myWcfService = new MyWcfServiceClient(new BasicHttpBinding (), GetEndpointAddress()))
{
//do stuff here
}
In my unit test i have the following mock setup
var mockMyWcfService = new Mock<IMyWcfService>();
Which is not creating a mock that gets used by the above code.
If i put parameter types into the constructor, that does not work either as Moq will only mock an interface, and a default empty constructor (i believe , from googling my previous error)
Also, although in other projects in the solution we use Unity for IOC, i do not believe i can do that in this project as the .Net adapter is called from a VB6 app, which has no app.config for me to specify all of the unity config.
Thanks
If I understand it correctly, you have a class that uses a MyWcfServiceClient() and you want to control it's lifetime within your class (ergo the using block) therefore you cannot pass in a mocked service.
e.g.
public interface IMyWcfService {
void DoSomething();
}
public class MyClass {
private readonly IMyWcfService myService;
public MyClass(IMyWcfService myService) {
this.myService = myService;
}
public void DoIt() {
myService.DoSomething();
}
}
What you can try is to use a provider to create the service and pass this in and use a default provider to generate the service when not unit testing.
e.g.
public interface IService : IDisposable {
}
public class DefaultService : IService {
public void Dispose() {
}
}
public interface IServiceProvider {
IService GetService();
}
public class DefaultServiceProvider : IServiceProvider {
public IService GetService() {
return new DefaultService();
}
}
public class Consumer {
private readonly IServiceProvider serviceProvider;
public Consumer() : this (new DefaultServiceProvider()){
}
internal Consumer(IServiceProvider serviceProvider) {
this.serviceProvider = serviceProvider;
}
public void DoIt() {
using (var service = serviceProvider.GetService()) {
// do stuff
}
}
}
I generally make the unit test constructors internal - personal preference, not required.
In the unit test you can create a mock provider that returns a mock service.

Categories

Resources