minicover doesn't work with init properties - c#

Steps to reproduce:
Create project in rootDir\src\ProjectToTest with class
public class Entity
{
public string Property {get;init;}
}
Create unit test project in rootDir\test\TestProject with test
public class UnitTest1
{
[Fact]
public void Test1()
{
var fixture = new Fixture();
var instance = fixture.Build<Entity>().With(x => x.Property, "1").Create();
}
}
Run in cmd:
dotnet clean
dotnet restore
dotnet build
dotnet minicover instrument
dotnet test --no-build
on last command occurs exception
System.InvalidProgramException : Common Language Runtime detected an invalid program

Related

Why the Xunit CollectionDefinition Not Working with Class Library in .NET 6 Web App?

When developing a web app, quite often we need to do unit testing against objects in class libraries. I run into the problem when trying to use Xunit "CollectionDefinition" feature to share content between multiple test cases. (see details in following sections)
TEST ENVIRONMENT
Windows 11 and Visula Studio 2022 community edition
.NET 6 Web App "XunitDemo" with a .NET 6 Class Library "DataHelper"
Packages:
Xunit 2.4.2
Xunit.runner.visualstudio 2.4.3
PROBLEM DESCRIPTION:
In order to test sharing content between following test cases, I wrote test code with following components
The class to be tested: DataHelper.TextHelper (see code segment 1)
Test project: DataHelperTests
In test project, created the "fixture" object TextHelperFixture (see code segment 2)
In test project, Created the xunit CollectionDefinition (see code segment 3)
To make sure the TextHelperFixture works correctly, I setup first test case: TextHelperFixtureTest (see code segment 4)
To test the content sharing between multiple test cases, I setup 2 separate test cases: CollectionDefTest1 & CollectionDefTest2 with [Collection(....)] attribute. Each has 1 test method (see code segments 5 and 6)
Testing Steps:
To verify the "fixture" object actually works, I run TextHelperFixtureTest and it passed with no error.
To test the "CollectionDefinition", I tried to execute first test method: CollectDefTest1.CollDefTest1. It failed with following error:
 DataHelperTests.CollectionDefTest1.CollDefTest1
Source: CollectionDefTest1.cs line 15
Duration:1 ms
Message: The following constructor parameters did not have matching fixture data: TextHelperFixture fixture
When running second test with CollectionDefTest2.CollDefTest2, the similar error occurred:
 DataHelperTests.CollectionDefTest2.CollDefTest1
Source: CollectionDefTest2.cs line 16
Duration: 1 ms
Message: The following constructor parameters did not have matching fixture data: TextHelperFixture thFixture
QUESTIONS
The test result of "TextHelperFixtureTest" showed that the "Fixture" object is working fine when it was directly instantiated inside of the test case. Why using the "CollectionDefinition" caused the error of unable to find the "Fixture" class?
I thought that it was possible the CollectionDefinition won't work with class library. I actually setup a console app with class library, The "CollectionDefinition" was working fine there. Why this problem occurs when the main project is a .NET 6 web app?
It will be greatly appreciated if anyone has suggestions and troubleshooting tips.
TEST CODE SEGMENTS
------ Code Segment 1: Class in library to be Tested ------
namespace DataHelper
{
public class TextHelper
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public TextHelper() { }
public TextHelper (string fn, string ln)
{
FirstName = fn;
LastName = ln;
}
public string GetFullName()
{
return $"{FirstName} {LastName}";
}
}
}
------ Code Segment 2: "Fixture" object in test project ------
using System;
namespace DataHelperTests
{
public class TextHelperFixture: IDisposable
{
public string FullName { get; private set; }
public TextHelperFixture()
{
TextHelper st = new TextHelper("Jason", "Williams");
FullName = st.GetFullName();
}
public void Dispose()
{
}
}
}
------ Code Segment 3: CollectionDefinition in Test project ------
using Xunit;
namespace DataHelperTests
{
[Collection("TextHelper Collection")]
public class TextHelperFixtureCollection : ICollectionFixture<TextHelperFixture> { }
}
------ Code Segment 4: Test case to verify "fixture" object ------
using Xunit;
namespace DataHelperTests
{
public class TextHelperFixtureTest
{
private TextHelperFixture _fxt;
public TextHelperFixtureTest()
{
_fxt = new TextHelperFixture();
}
[Fact]
public void FixtureTest()
{
Assert.NotNull(_fxt.FullName);
}
}
}
------ Code Segment 5: first test utilizes the Collection ------
using Xunit;
namespace DataHelperTests
{
[Collection("TextHelper Collection")]
public class CollectionDefTest1
{
private TextHelperFixture _fixture;
public CollectionDefTest1(TextHelperFixture fixture)
{
_fixture = fixture;
}
[Fact]
public void CollDefTest1()
{
string result = _fixture.FullName;
Assert.Contains("Jason", result);
}
}
}
------ Code Segment 6: second test case that ultilizes the collection ------
using Xunit;
namespace DataHelperTests
{
[Collection("TextHelper Collection")]
public class CollectionDefTest2
{
private TextHelperFixture _fixture;
public CollectionDefTest2(TextHelperFixture thFixture)
{
_fixture = thFixture;
}
[Fact]
public void CollDefTest1()
{
Assert.NotNull(_fixture.FullName);
}
}
}
You've done 99% of it perfectly (it's a pleasure to answer a question where someone has clearly taken the time to surface as much as possible in textbook fashion like here) - just a typo/mistake under
Code Segment 3: CollectionDefinition in Test project
you are using the [Collection] attribute as one correctly would on the Test Class, but you meant [CollectionDefinition], which is the counterpart for the definition bit...
(Putting this in long form for future readers - you obviously had it all sorted but just typo'd in this instance)

How to get current test fixture attribute

I run selenium tests, and I have created a custom Test Fixture attribute that I apply to each fixture 3 times, each time with a new driver so my tests can run 3 separate times in 3 separate browsers. It looks like this:
[TestFixture(typeof(InternetExplorerDriver))]
[TestFixture(typeof(FirefoxDriver))]
[TestFixture(typeof(ChromeDriver))]
class Edit<TWebDriver> : BaseTest<TWebDriver> where TWebDriver : IWebDriver, new()
{
[Test]
public void Test()
{
//test code
}
}
For my test fixtures, I mirror the web applications views in a 1:1 ratio - so the Dashboard\Index view in the web app code would be the Dashboard\Index folder for my tests that test the same view, therefore the test organization is very strict.
I am running into an issue that there are certain tests that should not run in certain browsers, such as IE. The majority of the tests need to however. What I am trying to do is for each test fixture
Is there any way to get the Test Fixture typeof value at test run time so I can do the following (pseudo code)...:
[Test]
public void Test()
{
if(testFixture typeof is InternetExplorerDriver)
{
Assert.Ignore("test not to be run in IE");
}
// all the test code
}
Please try the code modified below.
[TestFixture(typeof(InternetExplorerDriver))]
[TestFixture(typeof(FirefoxDriver))]
[TestFixture(typeof(ChromeDriver))]
class Edit<TWebDriver> : BaseTest<TWebDriver> where TWebDriver : IWebDriver, new()
{
private TWebDriver webDriver;
public Edit(TWebDriver webDriver)
{
this.webDriver = webDriver;
}
[Test]
public void Test()
{
//test code
if (this.webDriver.GetType() == typeof(InternetExplorerDriver))
{
Assert.Ignore("test not to be run in IE");
}
}
}

Running TestFixtures from multiple class files in NUnit

I have a simple NUnit project in C#. I have a file TestFixture.cs that successfully runs its four tests. If I want to add additional tests in a new CS file, how do I do this? If I simply copy the code from TestFixture.cs into a new TestFixture2.cs and rename the TestFixture classes to TestFixture3 and 4 respectively, they do not execute. I would think they would automatically run. Do I need to tell the runner specifically if it is a file other than TestFixture.cs? Here is my code:
namespace NUnitTest1
{
[TestFixture]
public class TestFixture3
{
[Test]
public void TestTrue()
{
Assert.IsTrue(true);
}
// This test fail for example, replace result or delete this test to see all tests pass
[Test]
public void TestFault()
{
Assert.IsTrue(true);
}
}
[TestFixture]
public class TestFixture4
{
[Test]
public void TestTrue()
{
Assert.IsTrue(true);
}
// This test fail for example, replace result or delete this test to see all tests pass
[Test]
public void TestFault()
{
Assert.IsTrue(true);
}
}
}
My unit test runs by executing a command line program using the following code:
namespace NUnitTest1
{
class Program
{
[STAThread]
static void Main(string[] args)
{
string[] my_args = { Assembly.GetExecutingAssembly().Location };
int returnCode = NUnit.ConsoleRunner.Runner.Main(my_args);
if (returnCode != 0)
Console.Beep();
}
}
}
NUnit will automatically get all types marked with TestFixture attribute from test assembly when you load it (it does not matter whether fixtures in one .cs file or in separate). Then NUnit will search for methods marked with Test or TestCase attributes and load them. If NUnit don't see some test, then make sure you loaded latest version of your test assembly.
NOTE: If you are using NUnit test runner, then there is nice setting Reload when test assembly changes. With this option turned on NUnit will automatically reload test assembly when you rebuild it in Visual Studio.

NUnit ignores test when requesting mock from AutoFixture/AutoMaq

I'm using NUnit with AutoFixture, AutoMoq and the Theory attribute.
Here is my test method,
[TestFixture]
public class TestClass
{
[Theory, AutoMoqData]
public void TestI(I i)
{ }
}
the interface
public interface I
{ }
and the attribute
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture().Customize(new AutoMoqCustomization()))
{ }
}
When I build my solution the test is discovered. When I run the test the following is written to the Output window:
NUnit 1.0.0.0 executing tests is started
Run started: [...].Test.dll
NUnit 1.0.0.0 executing tests is finished
Test adapter sent back a result for an unknown test case. Ignoring result for 'TestI(Mock<TestClass+I:1393>.Object)'.
When using xUnit.net the above test is run correctly. Why is not it working with NUnit?
I have the following Nuget packages installed in the test project:
AutoFixture 3.18.1
AutoFixture.AutoMoq 3.18.1
Moq 4.2.1402.2112
NUnit 2.6.3
NUnitTestAdapter 1.0
I'm running the test from within Visual Studio 2013 Professional. I also tried running the test in the separate GUI runner, with the same result.
The following NUnit test passes in Visual Studio 2013 with the TestDriven.Net add-in:
internal class AutoMoqDataAttribute : AutoDataAttribute
{
internal AutoMoqDataAttribute()
: base(
new Fixture().Customize(
new AutoMoqCustomization()))
{
}
}
public interface IInterface
{
}
public class Tests
{
[Test, AutoMoqData]
public void IntroductoryTest(IInterface i)
{
Assert.NotNull(i);
}
}
The built-in test runner doesn't discover the above test. This looks like a bug in the test runner.

ConfigurationManager code fails when called from NUNIT project

In my C# class project, I have a helper class which has the following property
public class Helper
{
public string ConnectionString
{
get
{
return ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
}
}
}
My following test fails when I call the Helper class from NUNIT project with error message: Failure: System.NullReferenceException : Object reference not set to an instance of an object.
[Test]
public void connection_string_exists()
{
string connection = new Helper().ConnectionString;
Assert.NotNull(connection);
}
If I run the line of code new Helper().ConnectionString from a asp.net project then it works. Why does the Test fail?
Please let me know.
I suspect your Nunit tests are part of a different project and when you run the tests, ConfigurationManager looks at the config file of your test project and does not find "MyConnectionString"

Categories