I am working with C# in Visual Studio 2015 Community, with NUnit3 and Rhino Mocks and attempting to write a test for a component of my system (it is NOT a unit test).
I have encountered a problem when trying to use a generated stub as the argument to a TestCaseData that is provided to a TestCaseSource. I get the following errors in the output window:
Test adapter sent back a result for an unknown test case. Ignoring result for 'MyTest(Castle.Proxies.IMyInterfaceProxy4c6c716794ef48818f41fd5012345ead)'.
Test adapter sent back a result for an unknown test case. Ignoring result for 'MyTest(Castle.Proxies.IMyInterfaceProxy4c6c716794ef48818f41fd5012345ead)'.
The test name appears in the VS2015 integrated test-runner when I rebuild the test project, but as soon I try to run it it becomes greyed out.
Here there is some sample code based on my test code:
using NUnit.Framework;
using Rhino.Mocks;
using System.Collections;
namespace FenixLib.Core.Tests
{
public interface IMyInterface
{
int Property { get; }
}
[TestFixture]
class TestMocks
{
[Test, TestCaseSource( "TestCases" )]
public void MyTest(IMyInterface what)
{
// Do stuff
}
public static IEnumerable TestCases()
{
yield return new TestCaseData ( CreateFake ( 2 ) );
yield return new TestCaseData ( CreateFake ( 4 ) );
}
public static IMyInterface CreateFake ( int something )
{
var fake = MockRepository.GenerateStub<IMyInterface> ();
fake.Stub ( x => x.Property ).Return ( something );
return fake;
}
}
}
I have been able to overcome the problem if I create a decorator class that wraps the generated stub:
public class Decorator : IMyInterface
{
IMyInterface decorated;
public Decorator ( IMyInterface decorated )
{
this.decorated = decorated;
}
public int Property
{
get
{
return decorated.Property;
}
}
}
And change the prior return fake; by return new Decorator ( fake );. Everything works fine then.
However this is a bit of a pain in my real scenario because my interface does not only have a single property as in this example but is more complex (and yes I know that VS2015 can generate the code for implementing through the decorated field, but that's not the point). Besides, it feels pointless to use RinhoMocks if I am going to end up creating an implementation of the interface I am wishing to not fully implement for my test purposes.
Anyway, what annoys me is that I do not understand why it does not work and therefore I ask:
Can anyone help me to understand why the code without the decorator did not work?
At discovery time, TestExplorer creates a process and asks our adapter to find tests. Your TestCaseSource method runs and generates the cases. It has a name generated by Moq.
Much later in the lifetime of the program, your test is executed by Visual studio, which creates a different process and asks the adapter to run the tests. Since we are running in a new process, the adapter has to discover (that is generate) the cases all over. Most likely, Moq generates them with a different name. The originally created cases are never run and NUnit runs these new cases, which, from the point of view of TestExplorer, were never discovered in the first place.
I haven't seen this symptom before, but we have a similar problem with random arguments being regenerated at execution time. It's essentially a problem with the architecture and could only be resolved if the Adapter could somehow keep the originally loaded test assembly around to be found by the execution process.
Related
I have the following DatabaseFixture which has worked well for all tests I have created up to this point. I use this fixture for integration tests so I can make real assertions on database schema structures.
public class DatabaseFixture : IDisposable
{
public IDbConnection Connection => _connection.Value;
private readonly Lazy<IDbConnection> _connection;
public DatabaseFixture()
{
var environment = Environment.GetEnvironmentVariable("ASPNET_ENVIRONMENT") ?? "Development";
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("AppSettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"AppSettings.{environment}.json", optional: true, reloadOnChange: true)
.Build();
_connection = new Lazy<IDbConnection>(() =>
{
var connection = new MySqlConnection(configuration["ConnectionStrings:MyDatabase"]);
connection.Open();
return connection;
});
}
public void Dispose()
{
Connection?.Dispose();
}
}
[CollectionDefinition("Database Connection Required")]
public class DatabaseConnectionFixtureCollection : ICollectionFixture<DatabaseFixture>
{
}
The problem I am facing is I now need to invoke a test method like MyDataIsAccurate(...) with each record from a table in the database. xUnit offers the [MemberData] attribute which is exactly what I need but it requires a static enumerable set of data. Does xUnit offer a clean way of sharing my DatabaseFixture connection instance statically or do I just need to suck it up and expose a static variable of the same connection instance?
[Collection("Database Connection Required")]
public class MyTests
{
protected DatabaseFixture Database { get; }
// ERROR: Can't access instance of DatabaseFixture from static context...
public static IEnumerable<object[]> MyData => Database.Connection.Query("SELECT * FROM table).ToList();
public MyTests(DatabaseFixture databaseFixture)
{
Database = databaseFixture;
}
[Theory]
[IntegrationTest]
[MemberData(nameof(MyData))]
public void MyDataIsAccurate(int value1, string value2, string value3)
{
// Assert some stuff about the data...
}
}
You cannot access the fixture from the code that provides the test cases (whether that is a MemberData property or a ClassData implementation or a custom DataAttribute subclass.
Reason
Xunit creates an AppDomain containing all the data for the test cases. It builds up this AppDomain with all of those data at the time of test discovery. That is, the IEnumerable<object[]>s are sitting in memory in the Xunit process after the test assembly is built, and they are sitting there just waiting for the tests to be run. This is what enables different test cases to show up as different tests in test explorer in visual studio. Even if it's a MemberData-based Theory, those separate test cases show up as separate tests, because it's already run that code, and the AppDomain is standing by waiting for the tests to be run. On the other hand, fixtures (whether class fixtures or collection fixtures) are not created until the test RUN has started (you can verify this by setting a breakpoint in the constructor of your fixture and seeing when it is hit). This is because they are meant to hold things like database connections that shouldn't be left alive in memory for long periods of time when they don't need to be. Therefore, you cannot access the fixture at the time the test case data is created, because the fixture has not been created.
If I were to speculate, I would guess that the designers of Xunit did this intentionally and would have made it this way even if the test-discovery-loads-the-test-cases-and-therefore-must-come-first thing was not an issue. The goal of Xunit is not to be a convenient testing tool. It is to promote TDD, and a TDD-based approach would allow anyone to pick up the solution with only their local dev tools and run and pass the same set of tests that everyone else is running, without needing certain records containing test case data to be pre-loaded in a local database.
Note that I'm not trying to say that you shouldn't do what you're trying, only that I think the designers of Xunit would tell you that your test cases and fixtures should populate the database, not the other way around. I think it's at least worth considering whether that approach would work for you.
Workaround #1
Your static database connection may work, but it may have unintended consequences. That is, if the data in your database changes after the test discovery is done (read: after Xunit has built up the test cases) but before the test itself is run, your tests will still be run with the old data. In some cases, even building the project again is not enough--it must be cleaned or rebuilt in order for test discovery to be run again and the test cases be updated.
Furthermore, this would kind of defeat the point of using an Xunit fixture in the first place. When Xunit disposes the fixture, you are left with the choice to either: dispose the static database connection (but then it will be gone when you run the tests again, because Xunit won't necessarily build up a new AppDomain for the next run), or do nothing, in which case it might as well be a static singleton on some service locator class in your test assembly.
Workaround #2
You could parameterize the test with data that allows it to go to the fixture and retrieve the test data. This has the disadvantage that you don't get the separate test cases listed as separate tests in either test explorer or your output as you would hope for with a Theory, but it does load the data at the time of the tests instead of at setup and therefore defeats the "old data" problem as well as the connection lifetime problem.
Summary
I don't think such a thing exists in Xunit. As far as I know, your options are: have the test data populate the database instead of the other way around, or use a never-disposed static singleton database connection, or pull the data in your test itself. None of these are the "clean" solution you were hoping for, but I doubt you'll be able to get much better than one of these.
There is a way of achieving what you want, using delegates. This extremely simple example explains it quite well:
using System;
using System.Collections.Generic;
using Xunit;
namespace YourNamespace
{
public class XUnitDeferredMemberDataFixture
{
private static string testCase1;
private static string testCase2;
public XUnitDeferredMemberDataFixture()
{
// You would populate these from somewhere that's possible only at test-run time, such as a db
testCase1 = "Test case 1";
testCase2 = "Test case 2";
}
public static IEnumerable<object[]> TestCases
{
get
{
// For each test case, return a human-readable string, which is immediately available
// and a delegate that will return the value when the test case is run.
yield return new object[] { "Test case 1", new Func<string>(() => testCase1) };
yield return new object[] { "Test case 2", new Func<string>(() => testCase2) };
}
}
[Theory]
[MemberData(nameof(TestCases))]
public void Can_do_the_expected_thing(
string ignoredTestCaseName, // Not used; useful as this shows up in your test runner as human-readable text
Func<string> testCase) // Your test runner will show this as "Func`1 { Method = System.String.... }"
{
Assert.NotNull(testCase);
// Do the rest of your test with "testCase" string.
}
}
}
In the OP's case, you could access the database in the XUnitDeferredMemberDataFixture constructor.
I am having troubles when testing a controller, because there are some lines at my Startup that are null when testing, I want to add a condition for run this lines only if it's not testing.
// Desired method that retrieves if testing
if (!this.isTesting())
{
SwaggerConfig.ConfigureServices(services, this.AuthConfiguration, this.ApiMetadata.Version);
}
The correct answer (although of no help): It should not be able to tell so. The application should to everything it does unaware if it is in productino or test.
However to test the application in a simpler setting, you can use fake modules or mock-up modules that are loaded instead of the heavy-weight production modules.
But in order to use that, you have to refactor your solution and use injection for instance.
Some links I found:
Designing with interfaces
Mock Objects
Some more on Mock objects
It really depends on which framework you use for testing. It can be MSTest, NUnit or whatever.
Rule of thumb, is that your application should not know whether it is tested. It means everything should be configured before actual testing through injection of interfaces. Simple example of how tests should be done:
//this service in need of tests. You must test it's methods.
public class ProductionService: IProductionService
{
private readonly IImSomeDependency _dep;
public ImTested(IImSomeDependency dep){ _dep = dep; }
public void PrintStr(string str)
{
Console.WriteLine(_dep.Format(str));
}
}
//this is stub dependency. It contains anything you need for particular test. Be it some data, some request, or just return NULL.
public class TestDependency : IImSomeDependency
{
public string Format(string str)
{
return "TEST:"+str;
}
}
//this is production, here you send SMS, Nuclear missle and everything else which cost you money and resources.
public class ProductionDependency : IImSomeDependency
{
public string Format(string str)
{
return "PROD:"+str;
}
}
When you run tests you configure system like so:
var service = new ProductionService(new TestDependency());
service.PrintStr("Hello world!");
When you run your production code you configure it like so:
var service = new ProductionService(new ProductionDependency());
service.PrintStr("Hello world!");
This way ProductionService is just doing his work, not knowing about what is inside it's dependencies and don't need "is it testing case №431" flag.
Please, do not use test environment flags inside code if possible.
UPDATE:
See #Mario_The_Spoon explanation for better understanding of dependency management.
I have the following DatabaseFixture which has worked well for all tests I have created up to this point. I use this fixture for integration tests so I can make real assertions on database schema structures.
public class DatabaseFixture : IDisposable
{
public IDbConnection Connection => _connection.Value;
private readonly Lazy<IDbConnection> _connection;
public DatabaseFixture()
{
var environment = Environment.GetEnvironmentVariable("ASPNET_ENVIRONMENT") ?? "Development";
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("AppSettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"AppSettings.{environment}.json", optional: true, reloadOnChange: true)
.Build();
_connection = new Lazy<IDbConnection>(() =>
{
var connection = new MySqlConnection(configuration["ConnectionStrings:MyDatabase"]);
connection.Open();
return connection;
});
}
public void Dispose()
{
Connection?.Dispose();
}
}
[CollectionDefinition("Database Connection Required")]
public class DatabaseConnectionFixtureCollection : ICollectionFixture<DatabaseFixture>
{
}
The problem I am facing is I now need to invoke a test method like MyDataIsAccurate(...) with each record from a table in the database. xUnit offers the [MemberData] attribute which is exactly what I need but it requires a static enumerable set of data. Does xUnit offer a clean way of sharing my DatabaseFixture connection instance statically or do I just need to suck it up and expose a static variable of the same connection instance?
[Collection("Database Connection Required")]
public class MyTests
{
protected DatabaseFixture Database { get; }
// ERROR: Can't access instance of DatabaseFixture from static context...
public static IEnumerable<object[]> MyData => Database.Connection.Query("SELECT * FROM table).ToList();
public MyTests(DatabaseFixture databaseFixture)
{
Database = databaseFixture;
}
[Theory]
[IntegrationTest]
[MemberData(nameof(MyData))]
public void MyDataIsAccurate(int value1, string value2, string value3)
{
// Assert some stuff about the data...
}
}
You cannot access the fixture from the code that provides the test cases (whether that is a MemberData property or a ClassData implementation or a custom DataAttribute subclass.
Reason
Xunit creates an AppDomain containing all the data for the test cases. It builds up this AppDomain with all of those data at the time of test discovery. That is, the IEnumerable<object[]>s are sitting in memory in the Xunit process after the test assembly is built, and they are sitting there just waiting for the tests to be run. This is what enables different test cases to show up as different tests in test explorer in visual studio. Even if it's a MemberData-based Theory, those separate test cases show up as separate tests, because it's already run that code, and the AppDomain is standing by waiting for the tests to be run. On the other hand, fixtures (whether class fixtures or collection fixtures) are not created until the test RUN has started (you can verify this by setting a breakpoint in the constructor of your fixture and seeing when it is hit). This is because they are meant to hold things like database connections that shouldn't be left alive in memory for long periods of time when they don't need to be. Therefore, you cannot access the fixture at the time the test case data is created, because the fixture has not been created.
If I were to speculate, I would guess that the designers of Xunit did this intentionally and would have made it this way even if the test-discovery-loads-the-test-cases-and-therefore-must-come-first thing was not an issue. The goal of Xunit is not to be a convenient testing tool. It is to promote TDD, and a TDD-based approach would allow anyone to pick up the solution with only their local dev tools and run and pass the same set of tests that everyone else is running, without needing certain records containing test case data to be pre-loaded in a local database.
Note that I'm not trying to say that you shouldn't do what you're trying, only that I think the designers of Xunit would tell you that your test cases and fixtures should populate the database, not the other way around. I think it's at least worth considering whether that approach would work for you.
Workaround #1
Your static database connection may work, but it may have unintended consequences. That is, if the data in your database changes after the test discovery is done (read: after Xunit has built up the test cases) but before the test itself is run, your tests will still be run with the old data. In some cases, even building the project again is not enough--it must be cleaned or rebuilt in order for test discovery to be run again and the test cases be updated.
Furthermore, this would kind of defeat the point of using an Xunit fixture in the first place. When Xunit disposes the fixture, you are left with the choice to either: dispose the static database connection (but then it will be gone when you run the tests again, because Xunit won't necessarily build up a new AppDomain for the next run), or do nothing, in which case it might as well be a static singleton on some service locator class in your test assembly.
Workaround #2
You could parameterize the test with data that allows it to go to the fixture and retrieve the test data. This has the disadvantage that you don't get the separate test cases listed as separate tests in either test explorer or your output as you would hope for with a Theory, but it does load the data at the time of the tests instead of at setup and therefore defeats the "old data" problem as well as the connection lifetime problem.
Summary
I don't think such a thing exists in Xunit. As far as I know, your options are: have the test data populate the database instead of the other way around, or use a never-disposed static singleton database connection, or pull the data in your test itself. None of these are the "clean" solution you were hoping for, but I doubt you'll be able to get much better than one of these.
There is a way of achieving what you want, using delegates. This extremely simple example explains it quite well:
using System;
using System.Collections.Generic;
using Xunit;
namespace YourNamespace
{
public class XUnitDeferredMemberDataFixture
{
private static string testCase1;
private static string testCase2;
public XUnitDeferredMemberDataFixture()
{
// You would populate these from somewhere that's possible only at test-run time, such as a db
testCase1 = "Test case 1";
testCase2 = "Test case 2";
}
public static IEnumerable<object[]> TestCases
{
get
{
// For each test case, return a human-readable string, which is immediately available
// and a delegate that will return the value when the test case is run.
yield return new object[] { "Test case 1", new Func<string>(() => testCase1) };
yield return new object[] { "Test case 2", new Func<string>(() => testCase2) };
}
}
[Theory]
[MemberData(nameof(TestCases))]
public void Can_do_the_expected_thing(
string ignoredTestCaseName, // Not used; useful as this shows up in your test runner as human-readable text
Func<string> testCase) // Your test runner will show this as "Func`1 { Method = System.String.... }"
{
Assert.NotNull(testCase);
// Do the rest of your test with "testCase" string.
}
}
}
In the OP's case, you could access the database in the XUnitDeferredMemberDataFixture constructor.
Here's the sample static method, say
public static void UpdateSchedule(int selectedScheduleId)
{
using (var dc = new MyDataContext())
{
var selectedSchedule = dc.Schedules.SingleOrDefault(p => p.ScheduleId == selectedScheduleId)
if selectedSchedule != null)
{
selectedSchedule.Name = name;
//and update other properties...
}
dc.SubmitChanges();
}
}
So what would be the correct approach to test on methods like this? Is there a way to avoid calling new MyDataContext() as it might increase the execution time of the unit test.
Also, I am using MsTest test framework in VS2012.
Static functions interfere with testing primarily because they:
Are difficult (sometimes impossible) to substitute from within a consumer
Tend to have "hidden" dependencies
Since you want to test the function itself, number 1 isn't an issue. However, number 2 is problematic because the static function is tightly coupled to the MyDataContext class.
If you want to test the static function without MyDataContext (that is, in isolation) you need to introduce a code seam. This requires some refactoring work, but we can do it fairly painlessly.
Consider if you had the following additional method:
public static void UpdateScheduleWithContext(int selectedScheduleId, IDataContext dc)
{
var selectedSchedule = dc.Schedules.SingleOrDefault(p => p.ScheduleId == selectedScheduleId)
if selectedSchedule != null)
{
selectedSchedule.Name = name;
//and update other properties...
}
dc.SubmitChanges();
}
This new function gives the consumer (i.e., the test) the ability to supply a test double for the data context. This is the seam.
Obviously, though, you don't want all consumers to explicitly provide a data context (which is why you had the original static function to begin with). So you can keep that function around, and just modify it:
public static void UpdateSchedule(int selectedScheduleId)
{
using (var dc = new MyDataContext())
{
UpdateScheduleWithDataContext(selectedScheduleId, dc);
}
}
If you don't have a seam like this, it will be impossible to test the function in isolation. As a result, an integration test would be the best you could hope for.
As Simon Whitehead said, it is impossible to do effective unit testing on static methods and objects. However, using the unit test framework in Visual Studio, you can create a 'unit test' function that is effectively a integration test. Tell Visual Studio to generate a Unit Test for UpdateSchedule, and then modify the function generated to set up the environment/state of the program such that the UpdateSchedule method can execute (create a database connection, instantiate classes, etc.). This includes ensuring that your database has records to update.
Once that is done, you can execute your integration test in the same manner that you would a unit test.
I have a Question for you guys.I have 2 unit tests which are calling webservices .The value that one unit-test returns should be used for another unit test method
Example
namespace TestProject1
{
public class UnitTest1
{
String TID = string.empty;
public void test1
{
//calling webservices and code
Assert.AreNotEqual(HoID, hID);
TID = hID;
}
public void test2
{
//calling webservices and code
string HID = TID // I need the TID value from the Above testcase here
Assert.AreNotEqual(HID, hID);
}
}
}
How can i store a value in one unittest and use that value in another unittest.
In general, you shouldn't write your tests like this. You cannot ensure that your tests will run in any particular order, so there's no nice way to do this.
Instead make the tests independent, but refactor the common part into it's own (non-test) method that you can call as part of your other test.
Don't reuse any values. Order in which tests are run is very often random (most common runners like NUnit's and Resharper's run tests in random order, some might even do so in parallel). Instead, simply call web service again (even if that means having 2 web service calls) in your second test and retrieve the value you need.
Each test (whether it's unit or integration) should have all the data/dependencies available for it to run. You should never rely on other tests to setup environment/data as that's not what they're written for.
Think of your tests in isolation - each single test is a separate being, that sets up, executes, and cleans up all that is necessary to exercise particular scenario.
Here's an example, following the outlines of Oleksi, of how you could organize this
String TID = string.empty;
[TestFixtureSetUp]
public void Given() {
//calling webservices and code
TID = hID;
//calling webservices and code
}
[Test]
public void assertions_call_1() {
...
}
public void assertions_on_call_2() {
if (string.IsNullOrEmpty(TID))
Assert.Inconclusive("Prerequisites for test not met");
...
}