C# - Nunit and sealed class - c#

I have these classes.
class ParentViewModel
public ParentViewModel(
AViewModel A,
BViewModel B)
{
// assigning to variables
}
public bool HasBeenFilled => A.HasBeenFilled || B.HasBeenFilled
public bool AnotherMethod => A.PropertyA && B.PropertyB
class AViewModel (sealed)
public bool HasBeenFilled => // some logic here
public bool PropertyA => // some logic here
class BViewModel (sealed)
public bool HasBeenFilled => // some logic here
public bool PropertyB => // some logic here
Now, if I want to test the ParentViewModel for methods HasBeenFilled and AnotherMethod I would write something like:
public void Test_HasBeenFilled()
{
var mockA = new Mock<AViewModel>(); // here comes the issue
var mockB = new Mock<BViewModel>();
mockA.Setup(x => x.HasBeenFilled).Returns(true); // what I want to test
mockB.Setup(x => x.HasBeenFilled).Returns(true);
var viewModel = new ParentViewModel(mockA.Object, mockB.Object);
Assert.Equals(viewModel.HasBeenFilled == true);
}
The issue is that I cannot create mocks over a sealed class.
I could create a base class for AViewModel and BViewModel but then in my parent class (f.e) I have to cast it to the specific object in the 'AnotherMethod' (for accessing PropertyA and Property B) --> what happen when I'll try to test it? My test will be like:
public void Test_AnotherMethod()
{
var mockA = new Mock<AViewModelBase>();
var mockB = new Mock<BViewModelBase>();
// cannot setup PropertyA and PropertyB here
var viewModel = new ParentViewModel(mockA.Object, mockB.Object);
Assert.Equals(viewModel.AnotherMethod == true); // I would expect an error
}
Another solution could be to create specific interface for both AViewModel and BViewModel but, to me, it feels like unnecessary (from development side). It seems like the unit tests are driven heavily my design.
So, my question: How would you address this scenario? Is all about a bad design?

Related

Mocking a concrete class with a virtual method

I want to test a class that depends on another class with the virtual method.
class DepClass
{
public virtual string Get() => "";
}
class HostClass
{
private _c;
public Host(DepClass c){ _c = c; }
public string Magic() => _c.Get();
}
Now I want to test the HostClass with Autofixture + NSubstitute.
My expectation:
Fixture.Freeze<DepClass>().Get().ReturnsForAnyArg("123");
var sut = Fixture.Create<HostClass>();
var res = sut.Magic(); //should be 123
As a fact, when I do Freeze().Get().Returns() the real Get method is being called.
How to customize Autofixture to mock all virtual methods?
Would be great not to discuss interface vs virtual methods, etc
Update
This does not work:
Fixture.Freeze<DepClass>().Get().ReturnsForAnyArgs("123");
At the same time, this works:
Substitute.For<DepClass>().Get().ReturnsForAnyArgs("123");
In addition to the answer
Another approach that might be not fit your needs: in my case, I expect that only direct dependencies can have virtual methods. all dependencies of the lower level will be mocked.
As result, I decided to go in a bit more specific way. The code below is an example, so you might be want to modify it before using it in your solution.
abstract class UnitTestBase<T>
{
protected IFixture Fixture { get; private set; }
protected IList<Type> ProxyTypes {get; private set;}
protected CreateSut(): T => Fixt.Create<T>();
[SetUp]
protected virtual Setup()
{
ProxyTypes = new List<Type>();
Fixture = new Fixture().Customize(new CompositeCustomization(
new AutoNSubstituteCustomization {
ConfigureMembers = true,
GenerateDelegates = true
})
);
SetupTypesToProxy();
Fixture.Customizations.Add(new SubstituteRelay(new ProxyExactTypesSpecification(ProxyTypes)));
}
protected virtual void SetupTypesToProxy()
=> typeof(T)
.GetConstructors(BindingFlags.Public | BindingFlags.Instance)
.SelectMany(ctorInfo => ctorInfo
.GetParameters()
.Select(paramInfo => paramInfo.ParameterType)
.Where(ShouldProxy))
.ForEach(t => ProxyTypes.Add(t));
private static bool ShouldProxy(Type type)
=> !type.GetTypeInfo().IsInterface && !type.GetTypeInfo().IsAbstract;
}
internal class ProxyExactTypesSpecification: IRequestSpecification
{
public ProxyExactTypesSpecification(
IEnumerable<Type> types
)
{
_proxyTypes = types ?? Type.EmptyTypes;
}
public bool IsSatisfiedBy(
object request
)
{
Argument.NotNull(request, nameof(request));
if (request is Type type)
return _proxyTypes.Contains(type);
return false;
}
private readonly IEnumerable<Type> _proxyTypes;
}
Because DepClass is neither an interface nor an abstract type, by default, AutoFixture will not rely on a mocking framework to create the instance, and will use the actual constructor from the type.
Since NSubstitute does not have the equivalent of Mock<T> or Fake<T> from other popular mocking frameworks, AutoFixture had to provide a special specimen builder, called SubstituteRelay, to fill in the gap. You can use this class as any other specimen builder to instruct the Fixture to return a mock when a specific type instance is requested.
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Customizations
.Add(new SubstituteRelay(new ExactTypeSpecification(typeof(DepClass))));
This construction is a bit lengthy so you could create a generic relay to shorten the syntax.
public class SubstituteRelay<T> : CompositeSpecimenBuilder
{
public SubstituteRelay()
: base(new SubstituteRelay(new ExactTypeSpecification(typeof(T))))
{
}
}
You should be able to write your test something like.
[Fact]
public void ReturnsExpectedValue()
{
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Customizations.Add(new SubstituteRelay<DepClass>());
fixture.Freeze<DepClass>().Get().ReturnsForAnyArgs("1234");
var sut = fixture.Create<HostClass>();
var actual = sut.Magic();
Assert.Equal("1234", actual);
}
To get closer to your intended API, you can create your own extension method that abstracts away the two lines of code that register the relay and freeze the instance.

c# mock return base method

I am writing a unit test case with NUnit framework to test our code.
The code has referenced to 3rd party libraries like below:
class MyClass: BaseClass
{
public void override FunctionA()
{
var a = BaseFunctionB();
}
}
we don't have sourcecode for BaseClass, but the BaseFunctionB is non-virtual.
I was trying to
Setup(x=> x.BaseFunctionB()).Reteruns("my values");
but it doesn't allow.
I just want to test the FunctionA in MyClass, I don't care whether it's correct in BasefunctionB.
How to test in this case?
----------------------------2018-01-03 updated---------------------------------
I made some update for the BaseClass:
public abstract class BaseClass1//we dont have source code for this class
{
public int GetValue()
{
//do something here
return 1;//
}
public abstract int GenerateOutPut();
}
class abstract class BaseClass2: BaseClass1
{
public new virtual int GetValue()
{
return base.GetValue();
}
}
class MyClass1: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
a += 1;
return a;
}
}
class MyClass2: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
a -= 1;
return a;
}
}
// there are many MyClass
class MyClassN: BaseClass2
{
public override int GenerateOutPut()
{
var a = GetValue();
//different logic here.
return a;
}
}
i made a class for testing MyClass1 like below:
class TestClass1: MyClass1
{
public override int GetValue()
{
return 100;
}
}
test case as below:
public void TestFunction()
{
var test = new TestClass1();
var result = test.GetValue();
assert.AreEqual(101, result);
}
Now I have to create many TestClas which looks not good. but in terms of running out code coverage, i have to make it( i try to use mock object to execute, there is no code covered in report, i guess because it create proxy and run it on proxy, so i create the same thing myself to test the original source code)
Do i have a better solution?
Creating the second base class and the new member to encapsulate the 3rd party dependency was a good idea. It allows you to override the member in derived classes. In general try to avoid mocking what you do not own. Instead encapsulate 3rd party dependencies behind an abstraction you control so as to allow you the flexibility to mock/stub/fake any desired behavior for testing.
Using MyClass1 from your example
public class MyClass1 : BaseClass2 {
public override int GenerateOutPut() {
var a = GetValue();
a += 1;
return a;
}
}
The following test can be done to verify the expected behavior from the subject under test. Note Moq allows for base members to be called by setting CallBase = true on the mocked object.
[TestClass]
public class MyClass1_Test {
[TestMethod]
public void MyClass1_Should_Generate_Output() {
//Arrange
var expected = 0;
var mock = new Mock<MyClass1>() {
CallBase = true //<-- let mock call base members
};
mock.Setup(_ => _.GetValue()).Returns(expected); // <-- mocked behavior
var sut = mock.Object; //<-- subject under test.
//Act
var actual = sut.GenerateOutPut();
//Assert
actual.Should().Be(expected + 1);
}
}
Which is almost like what you did manually but now via the mock proxy.

TDD How to Assert that a property of a POCO is set within a method that is being tested

We are creating a C# application using TDD and DI methodologies and NSubstitute.
We are writing a CreateThing method:
name and description strings as parameters
create a new Thing object
set the Name and Description properties of Thing from the method parameters
set the Status to Active
pass the Thing to a method on another class (via constructor injection) for further processing
We know how to write a test for the call to the other class by using Substitute.For and .Received().
How do we write tests for the Thing properties being set?
You can use Argument matchers namely Conditional matcher which looks like Arg.Is<T>(Predicate<T> condition). Your matcher could look like:
anotherClass.Received().Process(Arg.Is<Thing>(thing => !string.IsNullOrEmpty(thing.Name)));
Full listing:
public class Thing
{
public string Name { get; set; }
}
public class AnotherClass
{
public virtual void Process(Thing thing)
{
}
}
public class CreateThingFactory
{
private readonly AnotherClass _anotherClass;
public CreateThingFactory(AnotherClass anotherClass)
{
_anotherClass = anotherClass;
}
public void CreateThing()
{
var thing = new Thing();
thing.Name = "Name";
_anotherClass.Process(thing);
}
}
public class CreateThingFactoryTests
{
[Fact]
public void CreateThingTest()
{
// arrange
var anotherClass = Substitute.For<AnotherClass>();
var sut = new CreateThingFactory(anotherClass);
// act
sut.CreateThing();
// assert
anotherClass.Received().Process(Arg.Is<Thing>(thing => !string.IsNullOrEmpty(thing.Name)));
}
}

Deep Copy/Clone methods in a C# class hierarchy - Do I need a concrete implementation everywhere?

Let's say I have the following class hierarchy (base interface included):
IAction -> (abstract) BaseAction -> (concrete) ImmediateAction -> (concrete) MovementAction
Now, let's say IAction exposes a method (well, really a different interface that IAction implements does but let's keep things simple here!):
// Returns a new IAction instance deep copied from the current instance.
IAction DeepClone();
Good so far? We have our deep copy method, and ImmediateAction has some properties that it wants copied so it will provide not only an implementation of DeepClone(), but a copy constructor as well:
//Base Action implementation
protected BaseAction(BaseAction old)
{
this.something = old.something;
}
//Immediate Action Implementation
protected ImmediateAction(ImmediateAction old)
: base(old)
{
this.anything = old.anything;
}
public IAction DeepClone()
{
return new ImmediateAction(this);
}
Now, let's say MovementAction doesn't have anything inside of it that's relevant in a DeepClone() at all, so it doesn't implement the method or a copy constructor.
The problem that I'm having is this:
IAction x = new MovementAction();
IAction y = x.DeepClone();
//pleaseBeTrue is false
bool pleaseBeTrue = y is MovementAction;
Now, I understand what's going on here - MovementAction does not implement DeepClone(), so ImmediateAction.DeepClone() is called instead, which instantiates a new ImmediateAction. Hence, the type of y in the above example is ImmediateAction instead of MovementAction.
So, after this lengthy preamble, my question is this: what is the best practice for this type of situation? Am I stuck? Do I simply have to implement a DeepClone() method no matter what for every class along the hierarchy? Is the pattern that I am using here incorrect, and there's a better way?
One final note: I would like to avoid reflection if at all possible.
Could use an extension method and do incremental cloning
public static class DeepCopyExt
{
public static T DeepCopy<T>(this T item)
where T : ThingBase, new()
{
var newThing = new T();
item.CopyInto(newThing);
return newThing;
}
}
public abstract class ThingBase
{
public int A { get; set; }
public virtual void CopyInto(ThingBase target)
{
target.A = A;
}
}
public class ThingA : ThingBase
{
}
public class ThingB : ThingA
{
public int B { get; set; }
public override void CopyInto(ThingBase target)
{
var thingB = target as ThingB;
if(thingB == null)
{
throw new ArgumentException("target is not a ThingB");
}
thingB.B = B;
base.CopyInto(thingB);
}
}
class Program
{
static void Main(string[] args)
{
var b = new ThingB
{
A = 1,
B = 3
};
//c is ThingB
var c = b.DeepCopy();
var b1 = new ThingA
{
A = 1,
};
//c1 is ThingA
var c1 = b1.DeepCopy();
Debugger.Break();
}
}
So yes, you have two options:
Either implement DeepClone() each time and in details (list all not-shared properties)
Or use 'quick&dirty' but shared implementation using reflection
Typically you'd need to implement your clone method in the concrete classes. In fact this code you posted won't compile if ImmediateAction is abstract like you said at the top:
return new ImmediateAction(this);

C# polymorphism issue

I have a BL class named:A , DTO class named:DTO . Now assume I want to add some more properties in my DTO. So I derive a new DTO class from my existing DTO and add properties to it.Below is the code:
namespace TestConsole
{
class test
{
static void Main(string[] args)
{
B b = new B();
b.D.ID = 1;
b.D.Name = "4";
MyBLMethod(b);
}
static void MyBLMethod(A b)
{
MyDALMethod(b.D);
}
static void MyDALMethod(DTO dto)
{
int i = dto.ID;
string name = ((MyDTO)dto).Name;//I could not do this
//because i will get object cast error as i can't cast from
//parent to child
}
}
public class DTO
{
public int ID = 99;
public DTO()
{
}
public DTO(DTO source)
{
ID = source.ID;
}
}
public class MyDTO : DTO
{
public string Name = "";
public MyDTO() { }
public MyDTO(MyDTO source)
: base(source)
{
Name = source.Name;
}
}
public class A
{
private DTO _d;
public A()
{
D = new DTO();
}
public DTO D
{
get { return _d; }
set { _d = value; }
}
}
public class B : A
{
private MyDTO _md;
public B()
{
_md = new MyDTO();
}
public MyDTO D
{
get { return _md; }
set { _md = value; }
}
}
}
From Main (you can think it as UI) i am calling MyBLMethod (present in BL repository) and passing class object to it , and from BL repository i am calling my DAL. In DAL i have written this:
static void MyDALMethod(DTO dto)
{
int i = dto.ID;
string name = ((MyDTO)dto).Name;//I could not do this
//because i will get object cast error as i can't cast from
//parent to child
}
Could you suggest me how could i get the newly extended property (name in the example) in my DAL.
When B inherits A, it already owns a DTO attribute. So the problem is really that you are hidding this inheritance. You don't need a new property inside B class, just set it in your class constructor.
public class B : A
{
public B()
{
this.D = new MyDTO();
}
}
But, in your main class you will need a explicit cast in your property, just like below, since DTO does not have a "Name" property.
static void Main(string[] args)
{
B b = new B();
b.D.ID = 1;
((MyDTO)b.D).Name = "4";
MyBLMethod(b);
}
If the object is ACTUALLY of the base type, you can't just tack on the additional properties. Doesn't work that way, sorry.
What you want is to CONVERT the object (maybe). Make a constructor in your child class that can take a parent and copy all of it's stuff into itself - then you'll have the additional properties.
The reason that the cast fails, is that you are not passing a MyDTO object to the method, but a DTO object. The MyBLMethod method always sends the DTO object to the DAL even if there is a MyDTO object.
You haven't made the D property virtual. That means that when you use the D property on an A reference, you get the DTO object that the A class contains even if the actual object happens to the a B instance so that it also has a MyDTO object.
You can make the D property virtual to access the D property of the actual object instead of the one specified by the type of the reference.
Or you can cast the reference to B so that you can access it's MyDTO object instead of it's DTO object:
static void MyBLMethod(A b) {
MyDALMethod(((B)b).D);
}
Note that the B class contains both a DTO and a MyDTO object, which might not be what you really want.
It sounds like you are losing "resolution" because you are passing through a static business logic method. I would suggest revisiting that part rather than struggling with the DAL method first.
There may be a reason you're stuck with that though, so if you are, you can consider using reflection to find the properties you need or using an "as" cast and then testing for null in your dal method. If you aren't stuck with this design, I'd refactor my way out of the static method though. Static seems so easy and unfortunately there's a lot of code 'quality' tools pushing you to make methods static which forget to remind you can't easily change static methods to virtual methods later.
Allow B to pass A a DTO object in A's constructor. If needed, make the constructor protected. Then, have B.D cast A.D.
public class A
{
private DTO _d;
// New constructor.
protected A(DTO d)
{
_d = d;
}
// Old constructor calls new constructor.
public A() : this(new DTO())
{
}
public DTO D
{
get { return _d; }
set { _d = value; }
}
}
public class B : A
{
// Old B constructor calls new A constructor.
public B() : base(new MyDTO())
{
}
new public MyDTO D
{
// Getting D casts A.D instead of using an object exclusive to B.
get { return (MyDTO)base.D; }
set { base.D = value; }
}
}

Categories

Resources