NSubstitute: Mocking properties - c#

I created substitutes for Person and AddressBook classes in the unit Test.
The AddressBook class contains properties of type Person and name: SamplePerson.
public interface IAddressBook
{
Person SamplePerson { get; set; }
}
public class AddressBook : IAddressBook
{
public Person SamplePerson { get; set; }
public AddressBook(Person samplePerson)
{
SamplePerson = samplePerson;
}
}
public interface IPerson
{
string GetName(string name);
}
public class Person : IPerson
{
public string GetName(string name)
{
return name;
}
}
public void TestMethod1()
{
var personMock = Substitute.For<IPerson>();
var addressBookMock = Substitute.For<IAddressBook>();
addressBookMock.SamplePerson.Returns(personMock); //not working
addressBookMock.SamplePerson = personMock; //not working
addressBookMock.SamplePerson = (Person)personMock; //not working
Assert.AreEqual(1, 1);
}
I would like to assign mock variable of Person type to propeties of mock variable of type AddressBook.
Is this possible?

IAddressBook.SamplePerson property returns Person implementation and not IPerson interface, so your attempt to return IPerson will not work.
Either mock the Person class
var personMock = Substitute.For<Person>();
var addressBookMock = Substitute.For<IAddressBook>();
addressBookMock.SamplePerson.Returns(personMock);
or return an actual instance.
var person = new Person();
var addressBookMock = Substitute.For<IAddressBook>();
addressBookMock.SamplePerson.Returns(person);

Related

NSubstitute: Difference between Substitute.For<> and Substitute.ForPartsOf

I'm using NSubstitute. I have to fake a class and cannot dig out the difference of Substitute.For<...>() and Substitute.ForPartsOf<...>. I already read the documentation but don`t get the point, where the two behave different.
Substitute.For<>() creates full mock, while Substitute.ForPartsOf<> creates partial mock. For example:
[Test]
public void Test()
{
var person = Substitute.For<Person>();
person.GetAge().Returns(20);
var age = person.GetAge(); //returns 20
var name = person.GetName(); //returns empty string
var partialPerson = Substitute.ForPartsOf<Person>();
partialPerson.GetAge().Returns(20);
var age2 = partialPerson.GetAge(); //returns 20
var name2 = partialPerson.GetName(); //returns John
}
public class Person
{
public string Name { get; } = "John";
public int Age { get; } = 10;
public virtual int GetAge()
{
return Age;
}
public virtual string GetName()
{
return Name;
}
}
Generally ForPartsOf<> will use concrete implementation if it has not been substituted.

Moq: Mock SetUp method only returns null during test

I just added dependency inject into my application, and would like to run mock test on my methods to ensure they are working properly.
I have a domain class Person with the following properties:
public class Person : DomainBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
public char Gender { get; set; }
public DateTime DOB {get; set; }
}
I have a partial manager class that is shared with other domain type mangers:
public partial class Manager : IManager1
{
private IHiveTiesContext _ctx;
public Manager(IHiveTiesContext context)
{
_ctx = context;
}
}
The interface IManager1 was extracted from my PersonManager class and contains all need methods.
My PersonManager CreatePerson() method is being called and tested:
public partial class Manager : IManager1
{
public Person CreatePerson(string fn, string ln, DateTime dob, char gender, Guid RId)
{
var _person =_ctx.People.Add(new Person
{
FirstName = fn,
LastName = ln,
DOB = dob,
Gender = gender,
RowId = RId});
_ctx.SaveChanges();
return _person;
}
}
}
My context follows and once again I extracted an interface IHiveTiesContext from it.
public class HiveTiesContext : DbContext, IHiveTiesContext
{
public HiveTiesContext() : base("hiveties")
{
Database.SetInitializer<HiveTiesContext>(null);
}
public virtual IDbSet<Person> People { get; set; }
}
Finally I am trying to test CreatePerson like this:
public class PersonManagerMockTest
{
private static Guid personGuid;
[ClassInitialize]
public static void Init(TestContext test)
{
personGuid = Guid.NewGuid();
}
[TestMethod]
public void AddNewPerson()
{
//Arrange
var mockDbSet = new Mock<DbSet<Person>>();
var mockContext = new Mock<IHiveTiesContext>();
mockContext.Setup(x => x.People)
.Returns(mockDbSet.Object);
var manager = new Manager(mockContext.Object);
//Assert
var _person = manager.CreatePerson("Winston", "Gabriel", DateTime.Now, 'M', personGuid);
if(_person == null)
{
throw new Exception("NOT WORKING MAN!!!!");
}
var personid = mockContext.Object.People.Single(x => x.RowId == personGuid).Id;
//Act
mockDbSet.Verify(x => x.Add(It.IsAny<Person>()));
mockContext.Verify(x => x.SaveChanges());
}
}
My problem is that my Person object is never created, that is, it always returns a null value and the exception is always thrown. I believe I am telling it to return a Person entity, but I am not sure where I am going wrong. This is my first time using Moq and running Mock Unit Tests.
I appreciate any suggestions. Thank you.
You didn't set any behavior on the Add method of mockDbSet.
Add:(This line initialize the method to return the given person)
mockDbSet.Setup(x => x.Add(It.IsAny<Person>()))
.Returns <Person>(p => p);
Between the mocks:
var mockDbSet = new Mock<DbSet<Person>>();
mockDbSet.Setup(x => x.Add(It.IsAny<Person>()))
.Returns<Person>(p => p);
var mockContext = new Mock<IHiveTiesContext>();
mockContext.Setup(x => x.People)
.Returns(mockDbSet.Object);
...
I created a new signature/function in IHiveTiesContext to save Person object. (It's up to you now how you implement the interface).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SampleManager
{
public class Manager : IManager
{
private IHiveTiesContext _ctx;
public Manager(IHiveTiesContext context)
{
_ctx = context;
}
public Person CreatePerson(string fn, string ln, DateTime dob, char gender, Guid RId)
{
var person = _ctx.Save(fn, ln);
return person;
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public char Gender { get; set; }
public DateTime DOB { get; set; }
public Guid RowId { get; set; }
}
public interface IManager
{
Person CreatePerson(string fn, string ln, DateTime dob, char gender, Guid RId);
}
public interface IHiveTiesContext
{
Person Save(string fn, string ln);
}
}
/// <summary>
///A test for CreatePerson
///</summary>
[TestMethod()]
public void CreatePersonTest1()
{
var mock = new Mock<IHiveTiesContext>();
//fill up your expected object
mock.Setup(m => m.Save(It.IsAny<string>(), It.IsAny<string>())).Returns(new Person { FirstName = "William" });
Manager t = new Manager(mock.Object);
var results = t.CreatePerson(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<Char>(), It.IsAny<Guid>());
Assert.AreEqual("William", results.FirstName);
}

Create proxy from existing object

Using Castle.DynamicProxy, what is the best way to create a proxy from an existing class instance?
// The actual object
Person steve = new Person() { Name = "Steve" };
// Create a proxy of the object
Person fakeSteve = _proxyGenerator.CreateClassProxyWithTarget<Person>(steve, interceptor)
// fakeSteve now has steve as target, but its properties are still null...
Here's the Person class:
public class Person
{
public virtual string Name { get; set; }
}
Here's the interceptor class:
public class PersonInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Person p = invocation.InvocationTarget as Person;
if (invocation.Method.Name.Equals(get_Name)
{
LoadName(p);
}
}
private void LoadName(Person p)
{
if (string.IsNullOrEmpty(p.Name))
{
p.Name = "FakeSteve";
}
}
}
If your Person class has only non-virtual properties the proxy can't access them. Try to make the properties virtual.
http://kozmic.net/2009/02/23/castle-dynamic-proxy-tutorial-part-vi-handling-non-virtual-methods/

Deep copy of List<T> with extension method

I have this class :
public class Person : ICloneable
{
public string FirstName { get; set; }
public string LastName { get; set; }
public object Clone()
{
return this;
}
}
An extension method :
public static class MyHelper
{
public static IEnumerable<T> Clone<T>(this IEnumerable<T> collection) where T : ICloneable
{
return collection.Select(item => (T)item.Clone());
}
}
I'd like use it in this case :
var myList = new List<Person>{
new Person { FirstName = "Dana", LastName = "Scully" },
new Person{ FirstName = "Fox", LastName = "Mulder" }
};
List<Person> myCopy = myList.Clone().ToList<Person>();
When I change in the "immediat window" a value of myCopy, there is a change in the orginial list too.
I'd like have both list completely independent
I missed something ?
Your implementation of Clone is wrong.
Try this:
public object Clone()
{
return MemberwiseClone();
}
Your clone method returns the same object.
You should implement it like this
public class Person : ICloneable
{
public string FirstName { get; set; }
public string LastName { get; set; }
public object Clone()
{
return new Person { FirstName = this.FirstName, LastName = this.LastName };
}
}
Apart from the issue with your Clone method inside your Person class you need to return a new list in your extension method also
return collection.Select(item => (T)item.Clone()).ToList();
This is because the Select method is from Linq which uses deferred execution. If you change the original list then the list of 'myCopy' will also change.

In C#, how to instantiate a passed generic type inside a method?

How can I instantiate the type T inside my InstantiateType<T> method below?
I'm getting the error: 'T' is a 'type parameter' but is used like a 'variable'.:
(SCROLL DOWN FOR REFACTORED ANSWER)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGeneric33
{
class Program
{
static void Main(string[] args)
{
Container container = new Container();
Console.WriteLine(container.InstantiateType<Customer>("Jim", "Smith"));
Console.WriteLine(container.InstantiateType<Employee>("Joe", "Thompson"));
Console.ReadLine();
}
}
public class Container
{
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson
{
T obj = T();
obj.FirstName(firstName);
obj.LastName(lastName);
return obj;
}
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public class Customer : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
}
public class Employee : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeNumber { get; set; }
}
}
REFACTORED ANSWER:
Thanks for all the comments, they got me on the right track, this is what I wanted to do:
using System;
namespace TestGeneric33
{
class Program
{
static void Main(string[] args)
{
Container container = new Container();
Customer customer1 = container.InstantiateType<Customer>("Jim", "Smith");
Employee employee1 = container.InstantiateType<Employee>("Joe", "Thompson");
Console.WriteLine(PersonDisplayer.SimpleDisplay(customer1));
Console.WriteLine(PersonDisplayer.SimpleDisplay(employee1));
Console.ReadLine();
}
}
public class Container
{
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson, new()
{
T obj = new T();
obj.FirstName = firstName;
obj.LastName = lastName;
return obj;
}
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public class PersonDisplayer
{
private IPerson _person;
public PersonDisplayer(IPerson person)
{
_person = person;
}
public string SimpleDisplay()
{
return String.Format("{1}, {0}", _person.FirstName, _person.LastName);
}
public static string SimpleDisplay(IPerson person)
{
PersonDisplayer personDisplayer = new PersonDisplayer(person);
return personDisplayer.SimpleDisplay();
}
}
public class Customer : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
}
public class Employee : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeNumber { get; set; }
}
}
Declare your method like this:
public string InstantiateType<T>(string firstName, string lastName)
where T : IPerson, new()
Notice the additional constraint at the end. Then create a new instance in the method body:
T obj = new T();
Couple of ways.
Without specifying the type must have a constructor:
T obj = default(T); //which will produce null for reference types
With a constructor:
T obj = new T();
But this requires the clause:
where T : new()
To extend on the answers above, adding where T:new() constraint to a generic method will require T to have a public, parameterless constructor.
If you want to avoid that - and in a factory pattern you sometimes force the others to go through your factory method and not directly through the constructor - then the alternative is to use reflection (Activator.CreateInstance...) and keep the default constructor private. But this comes with a performance penalty, of course.
you want new T(), but you'll also need to add , new() to the where spec for the factory method
A bit old but for others looking for a solution, perhaps this could be of interest: http://daniel.wertheim.se/2011/12/29/c-generic-factory-with-support-for-private-constructors/
Two solutions. One using Activator and one using Compiled Lambdas.
//Person has private ctor
var person = Factory<Person>.Create(p => p.Name = "Daniel");
public static class Factory<T> where T : class
{
private static readonly Func<T> FactoryFn;
static Factory()
{
//FactoryFn = CreateUsingActivator();
FactoryFn = CreateUsingLambdas();
}
private static Func<T> CreateUsingActivator()
{
var type = typeof(T);
Func<T> f = () => Activator.CreateInstance(type, true) as T;
return f;
}
private static Func<T> CreateUsingLambdas()
{
var type = typeof(T);
var ctor = type.GetConstructor(
BindingFlags.Instance | BindingFlags.CreateInstance |
BindingFlags.NonPublic,
null, new Type[] { }, null);
var ctorExpression = Expression.New(ctor);
return Expression.Lambda<Func<T>>(ctorExpression).Compile();
}
public static T Create(Action<T> init)
{
var instance = FactoryFn();
init(instance);
return instance;
}
}
You can also use reflection to fetch the object's constructor and instantiate that way:
var c = typeof(T).GetConstructor();
T t = (T)c.Invoke();
Using a factory class to build your object with compiled lamba expression: The fastest way I've found to instantiate generic type.
public static class FactoryContructor<T>
{
private static readonly Func<T> New =
Expression.Lambda<Func<T>>(Expression.New(typeof (T))).Compile();
public static T Create()
{
return New();
}
}
Here is the steps I followed to set up the benchmark.
Create my benchmark test method:
static void Benchmark(Action action, int iterationCount, string text)
{
GC.Collect();
var sw = new Stopwatch();
action(); // Execute once before
sw.Start();
for (var i = 0; i <= iterationCount; i++)
{
action();
}
sw.Stop();
System.Console.WriteLine(text + ", Elapsed: {0}ms", sw.ElapsedMilliseconds);
}
I've also tried using a factory method:
public static T FactoryMethod<T>() where T : new()
{
return new T();
}
For the tests I've created the simplest class :
public class A { }
The script to test:
const int iterations = 1000000;
Benchmark(() => new A(), iterations, "new A()");
Benchmark(() => FactoryMethod<A>(), iterations, "FactoryMethod<A>()");
Benchmark(() => FactoryClass<A>.Create(), iterations, "FactoryClass<A>.Create()");
Benchmark(() => Activator.CreateInstance<A>(), iterations, "Activator.CreateInstance<A>()");
Benchmark(() => Activator.CreateInstance(typeof (A)), iterations, "Activator.CreateInstance(typeof (A))");
Results over 1 000 000 iterations:
new A(): 11ms
FactoryMethod A(): 275ms
FactoryClass A .Create(): 56ms
Activator.CreateInstance A (): 235ms
Activator.CreateInstance(typeof (A)): 157ms
Remarks: I've tested using both .NET Framework 4.5 and 4.6 (equivalent results).
Instead of creating a function to Instantiate the type
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson, new()
{
T obj = new T();
obj.FirstName = firstName;
obj.LastName = lastName;
return obj;
}
you could have done it like this
T obj = new T { FirstName = firstName, LastName = lastname };

Categories