xUnit.net Theory where MemberData is from derived class - c#

Using xUnit.net, it is possible for a Theory to have its MemberData originate from a derived class?
public abstract class BaseTest
{
public abstract IEnumerable<object[]> Data();
[Theory]
[MemberData(nameof(Data))]
public void TestData(string expected, string actual)
{
// assert goes here
}
}
public class ComplexTest : BaseTest
{
public override IEnumerable<object[]> Data()
{
// data goes here
}
}
The code above results in the following error message:
System.NotSupportedException : Specified method is not supported.

Another way of doing this (and IMO cleaner), is to put your test scenarios in their own specific classes and just define each scenario set as a separate MemberData attribute:
public class BaseTest
{
[Theory]
[MemberData(nameof(TestScenarios1.Data), MemberType = typeof(TestScenarios1)]
[MemberData(nameof(TestScenarios1.MoreData), MemberType = typeof(TestScenarios1)]
[MemberData(nameof(TestScenarios2.DifferentData), MemberType = typeof(TestScenarios2)]
public void TestData(string expected, string actual)
{
// assert goes here
}
}
public class TestScenarios1
{
public static IEnumerable<object[]> Data()
{
// data goes here
}
public static IEnumerable<object[]> MoreData()
{
// data goes here
}
}
public class TestScenarios2
{
public static IEnumerable<object[]> DifferentData()
{
// data goes here
}
}

As far as I know, this is not possible. MemberData's data is required to be static, therefore the data must originate from its own class.
public static IEnumerable<object[]> Data()
{
// data goes here
}
[Theory]
[MemberData(nameof(Data))]
public void TestData(string expected, string actual)
{
// assert goes here
}

You're correct in your answer. Posting this non-answer in case it happens to spark an idea.
MemberData can be passed params, which might help depending on your specific scenario?
Other than that, the best you can prob do is to put a forwarder:
public abstract class BaseTest
{
protected void RunTest(string expected, string actual)
{
Assert.Equal(expected, actual);
}
}
public class ComplexTest : BaseTest
{
static IEnumerable<object[]> Data() =
{
{ "a", "a" }
}
[Theory, MemberData(nameof(Data))]
void TestData(expected, actual) => base.RunTest(expected, actual);
}

Another way is to add MemberData only to derived class.
It will check members by name and take the correct one from the current class.
The only thing that analyzer with warn that you must specify member in base class (that by default treated as an error), so you have to disable this rule. If you try to specify this method in both classes - base and derived only base classes would be used.
The issue about analyzer described in xunit github: https://github.com/xunit/xunit/issues/1243
Your example may look:
public abstract class BaseTest
{
[Theory]
#pragma warning disable xUnit1015 // MemberData must reference an existing member
[MemberData(nameof(Data))]
#pragma warning restore xUnit1015 // MemberData must reference an existing member
public void TestData(string expected, string actual)
{
// assert goes here
}
}
public class ComplexTest : BaseTest
{
public static IEnumerable<object[]> Data()
{
return data;
// data goes here
}
}

Related

How to register dependencies based on the class they are required from(using built-in IOC-container in ASP CORE)

I am trying to register different implementations of one interface and depending on the classes, which are using these implementations, certain one to be passed.
public interface ITest { }
public class Test1 : ITest { }
public class Test2 : ITest { }
public class DoSmthWhichCurrentlyNeedsTest1
{
private ITest test;
public DoSmthWhichCurrentlyNeedsTest1(ITest test)
{
this.test = test;
}
}
public class DoSmthWhichCurrentlyNeedsTest2
{
private ITest test;
public DoSmthWhichCurrentlyNeedsTest2(ITest test)
{
this.test = test;
}
}
Current solution:
services.AddTransient(x=>new DoSmthWhichCurrentlyNeedsTest1(new Test1()));
services.AddTransient(x=>new DoSmthWhichCurrentlyNeedsTest2(new Test2()));
This works well unless you have a classes with lots of dependencies, where "x.GetRequiredService" should be called for every dependency in the constructor.
What I am looking for is something like this:
services.AddTransient<ITest, Test1>
(/*If ITest is required by DoSmthWhichCurrentlyNeedsTest1*/);
services.AddTransient<ITest, Test2>
(/*If ITest is required by DoSmthWhichCurrentlyNeedsTest2*/);
Is there any other way I have missed for this purpose?
This works well unless you have a classes with lots of dependencies, where "x.GetRequiredService" should be called for every dependency in the constructor.
This is a good use-case for ActivatorUtilities.CreateInstance. Here's an example:
services.AddTransient(sp =>
ActivatorUtilities.CreateInstance<DoSmthWhichCurrentlyNeedsTest1>(sp, new Test1()));
ActivatorUtilities.CreateInstance<T> creates an instance of the type specified (DoSmthWhichCurrentlyNeedsTest1 in this example) using a combination of the DI container and any additional parameters you pass. The first argument passed in is the IServiceProvider and any additional parameters are used to provide explicit values by type.
In the example shown, ActivatorUtilities.CreateInstance will:
Look for a suitable constructor for DoSmthWhichCurrentlyNeedsTest1 and analyse its parameters.
Match anything you provide as additional parameters by assignable type against constructor parameters. We provide an instance of Test1 which is assignable to ITest, so that is used in the next step.
Create an instance of DoSmthWhichCurrentlyNeedsTest1 by matching parameters with the values you provided. For anything that you didn't provide, it attempts to resolve the values from the DI container using GetService.
This affords you the convenience of not having to worry about connecting all the DI-provided dependencies for DoSmthWhichCurrentlyNeedsTest1 while still allowing you to specify those you do care about.
Here is a working demo like below:
1.Interface:
public interface ITest {
string play();
}
2.implement class:
public class Test1 : ITest
{
public string play()
{
return "111";
}
}
public class Test2 : ITest
{
public string play()
{
return "222";
}
}
3.test class:
public class DoSmthWhichCurrentlyNeedsTest1
{
private IEnumerable<ITest> test;
public DoSmthWhichCurrentlyNeedsTest1(IEnumerable<ITest> test)
{
this.test = test;
}
public string Get()
{
var flag = test.FirstOrDefault(h => h.GetType().Name == "Test1");
var value = flag?.play();
return value;
}
}
public class DoSmthWhichCurrentlyNeedsTest2
{
private IEnumerable<ITest> test;
public DoSmthWhichCurrentlyNeedsTest2(IEnumerable<ITest> test)
{
this.test = test;
}
public string Get()
{
var flag = test.FirstOrDefault(h => h.GetType().Name == "Test2");
var value = flag?.play();
return value;
}
}
4.Startup.cs:
services.AddTransient<ITest, Test1>();
services.AddTransient<ITest, Test2>();
5.Result:

RhinoMock - mocking multiple stubs for the same class

Say I have a class that is being called from within my MainClass method that I am testing.
public class MainClass
{
private readonly SubClass;
// constructor not shown
public method TestMethod()
{
var data = SubClass.MethodA();
// ...some code
var moreData = SubClass.MethodB(someOtherData);
// ...more code
}
}
Using RhinoMock, I'd like to create a stub for SubClass.MethodA() to return a specified set of data in the test, however when calling SubClass.MethodB(), I want to call the original implementation.
I wouldn't want to break out the SubClass' two methods out into their own classes as they fit in SubClass. Is there a way in RhinoMock to stub out one method while calling another method in the same class (that is not a stub)?
I would use the extract and override test pattern and a simple stub for this.
This doesn't explicitly use Rhino though but will do for your scenario.
If you don't want to go down this path consider injecting Subclass into MainClass via a constuctor, public setter or parameter, and then you can have more control of mocking subclass first.
The idea is to make a virtual method that a sub class stub can override to take control of the behaviour of a part of a class under test.
public class MainClass
{
private readonly SubClass _subClass;
// constructor not shown
public void TestMethod()
{
var data = SubClassMethodACall();
// ...some code
var someOtherData = "";
var moreData = _subClass.MethodB(someOtherData);
// ...more code
}
protected virtual string SubClassMethodACall()
{
return _subClass.MethodA();
}
}
public class SubClass
{
public string MethodA()
{
return null;
}
public string MethodB(string s)
{
return null;
}
}
namespace Tests.Unit
{
public class MainClassStub : MainClass
{
private readonly string _returnValueForMethodA;
public MainClassStub(string returnValueForMethodA)
{
_returnValueForMethodA = returnValueForMethodA;
}
protected override string SubClassMethodACall()
{
return _returnValueForMethodA;
}
}
[TestFixture]
public class TestClass
{
[Test]
public void TestMethod()
{
var mainClass = new MainClassStub("this is the test value returned");
//.. rest of test
}
}
}

How to test a virtual method defined in an abstract class?

I need to unit-test a virtual method defined in an abstract class. But the base class is abstract, so I can't create an instance of it. What do you recommend me to do?
This is a follow up to the following question: I am thinking about if it is possible to test via an instance of a subclass of the abstract class. Is it a good way? How can I do it?
There's no rule that says a unit test can't define its own classes. This is a fairly common practice (at least for me anyway).
Consider the structure of a standard unit test:
public void TestMethod()
{
// arrange
// act
// assert
}
That "arrange" step can include any reasonable actions (without side-effects outside of the test) which set up what you're trying to test. This can just as easily include creating an instance of a class whose sole purpose is to run the test. For example, something like this:
private class TestSubClass : YourAbstractBase { }
public void TestMethod()
{
// arrange
var testObj = new TestSubClass();
// act
var result = testObj.YourVirtualMethod();
// assert
Assert.AreEqual(123, result);
}
I'm not sure what your abstract class looks like, but if you have something like:
public abstract class SomeClass
{
public abstract bool SomeMethod();
public abstract int SomeOtherMethod();
public virtual int MethodYouWantToTest()
{
// Method body
}
}
And then, as #David suggested in the comments:
public class Test : SomeClass
{
// You don't care about this method - this is just there to make it compile
public override bool SomeMethod()
{
throw new NotImplementedException();
}
// You don't care about this method either
public override int SomeOtherMethod()
{
throw new NotImplementedException();
}
// Do nothing to MethodYouWantToTest
}
Then you just instantiate Test for your unit test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
SomeClass test = new Test();
// Insert whatever value you expect here
Assert.AreEqual(10, test.MethodYouWantToTest());
}
}

Stubbing Method with Base Class Type Parameter in Rhino Mocks

I'm trying to stub out a mock with a base class parameter, and have it return the same value for every call. I can't seem to get it to work correctly, and I can't get the wording correct on Google.
Basic data structures
public abstract class Base { }
public class BaseImplA : Base { }
public class BaseImplB : Base { }
public interface IDoStuff
{
bool DoStuff(Base b);
}
Implementation:
var MockDoStuff = MockRepository.GenerateMock<IDoStuff>();
MockDoStuff.Stub(x => x.DoStuff<Arg<Base>.Is.TypeOf);
.Return(true);
The stub isn't returning true because it's type checking to BaseImpl instead of Base.
What do I need to change to get it to accept Base rather than adding stubs for each of my BaseImpl-esque types?
There are syntax errors in your sample implementation code. Furthermore, in order to set a concrete method of a Mock to return a value, the target method must be marked Virtual or Override.
Here is code that should work as desired:
public abstract class Base { }
public class BaseImplA : Base { }
public class BaseImplB : Base { }
public class IDoStuff
{
public virtual bool DoStuff(Base b)
{
return true;
}
}
Implementation
public void TestMethod1()
{
var mockDoStuff = MockRepository.GenerateMock<IDoStuff>();
mockDoStuff.Stub(x => x.DoStuff(Arg<Base>.Is.Anything)).Return(true);
Assert.IsTrue(mockDoStuff.DoStuff(new BaseImplA()));
}

c# constructor vs initialize

Doing TDD and want to isolate the method under test: Direct();
However, when the test creates MyClass, SomeClass.SetupStuff(); blows up (NotImplementedException). So, modified the IMyClass interface to have a Configure(); method that can be called after MyClass construction to avoid the exception.
Question: Is this an accepted way of handling this scenario or is there some basic OOP principal that this breaks?
public class MyClass : IMyClass
{
public MyClass()
{
// class with static method that sets stuff up
SomeClass.SetupStuff();
}
public void IMyClass.Direct()
{
// want to test this
}
}
vs
public class MyClass : IMyClass
{
public MyClass()
{
}
public void IMyClass.Direct()
{
// want to test this
}
//
public void IMyClass.Configure()
{
// class with static method that sets stuff up
SomeClass.SetupStuff();
}
}
One way to avoid such problems is to use dependency injection
public class MyClass : IMyClass
{
public MyClass(ISomeClass someClass)
{
someClass.SetupStuff();
}
public void IMyClass.Direct()
{
// want to test this
}
}
By decoupling your class from SomeClass, you are free to provide a mock implementation of ISomeClass during test and can provide a full implementation at runtime.

Categories