moq and the "as" keyword - c#

I'm attempting to provide a mock that will help me test:
ClaimsPrincipal princple = Thread.CurrentPrincipal as ClaimsPrincipal;
However from what I can tell, the "as" keyword returns null even though I can see in the debugger Thread.CurrentPrincipal is the mock.
To test the theory I put together this short demo:
void Main()
{
var userMock = new Mock<IUser>();
userMock.Setup(w => w.UserId).Returns(1);
var user = userMock.Object as User;
user.Dump(); // null
}
public interface IUser
{
int UserId { get; set; }
}
public class User : IUser
{
public int UserId { get; set; }
}
How can I provide moq's for code that use the as keyword in the background?
From what I understand perhaps I need to provide a way for the proxy to cast back?
I sort of realise that this isn't possible, but wondered what people's approaches are to solving this.

When you create mock
var userMock = new Mock<IUser>();
then Moq dynamically creates class which implements IUser interface. That class has no relation to other implementations of this interface (like User class). That's why mock object is IUser but it is not User:
var user = userMock.Object as User; // will be null

I think I've found a work around, I understand I should be mocking against interfaces and shouldn't mock concrete classes, but this may have to do until I can refactor the dependencies.
The trick is to mock the concrete class Mock<User>() and use the As<IUser>() to mock the properties etc.
void Main()
{
var userMock = new Mock<User>();
userMock.As<IUser>().Setup(w => w.UserId).Returns(1);
var user = userMock.Object as User;
user.Dump(); // not null
}
public interface IUser
{
int UserId { get; set; }
}
public class User : IUser
{
public int UserId { get; set; }
}
I think I missed trying this as I've been always mocking to the interfaces in the past.

Related

Moq for single line multiple property code

I have these interfaces
public interface Interface1 { Interface2 Items {get;} }
public interface Interface2 { Guid? ApplicationTypeId { get; } }
public interface Interface3 { Class1 Item {get;} }
public interface Interface4 { Guid? ApplicationId { get; set; } }
A class inherits the first interface
public class Class1 : Interface1 {
public Interface2 Items { get; }
}
Another class which consists of few guids
public static class ContentTypeIds
{
public static Guid ContentGuid1 => new Guid("{11798e9d-a167-4cfc-8cfa-9a24fd6caf25}");
public static Guid ContentGuid2 => new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
}
I need to unit test the following property
private readonly Interface3 _interface3;
public Ticket Current
{
get
{
//This line is very complicated
Interface4 itemByContentType = _interface3.Item?.Items.GetItemByContentType(ContentTypeIds.ContentGuid2);
if ( itemByContentType?.ContentId != null )
return Get(itemByContentType.ContentId.Value);
return null;
}
}
My test class goes here
[Test]
public class TestClass {
var mock1 = new Mock<Interface1>();
var mock2 = new Mock<Interface2>();
var mock3 = new Mock<Interface3>();
mock1.SetupAllProperties();
mock2.SetupAllProperties();
mock3.SetupAllProperties();
}
The value for 'itemByContentType' goes null.
Could anyone help me to make it simple and testable as it is getting complicated to test this property? I'm using Moq. I will appreciate any help.
Thanks
I'm not an expert on Moq, but it looks like its SetupAllProperties method simply sets up all the properties to act like properties (i.e. the object it creates has a persistent member which can support GET/SET operation). If this isn't done, then as I understand it, the properties will still be available, but they'll always resolve to null. This is very handy when preparing the Mock objects, but on its own, though, that doesn't setup the properties with any sort of value.
I think what you should be doing is using Moq's SetupGet in conjunction with the Returns method to prepare the GET of the Items property with a specific value.
Here is some (simplified) sample code, to demonstrate this:
public interface IFoo { Guid? ApplicationId { get; set; } }
public interface IBar { IFoo Items { get; } }
class Program
{
static void Main(string[] args)
{
// SETUP
// Prepare mocks
Mock<IFoo> MockFoo = new Mock<IFoo>();
Mock<IBar> MockBar = new Mock<IBar>();
// Seting up properties allows us read/write Foo's ApplicationId
MockFoo.SetupAllProperties();
// The mocked Foo object should be what's returned when Items is requested
var expectedFoo = MockFoo.Object;
// Setup the Bar object to return that mocked Foo
MockBar.SetupGet(x => x.Items).Returns(expectedFoo);
// The value written here will be persistent due to SetupAllProperties
expectedFoo.ApplicationId = new Guid("{7d22f5bb-37fd-445a-b322-2fa1b108d260}");
// ACTION
// When the "Items" property is accessed, the IFoo we get should be what we mocked...
var actualFoo = MockBar.Object.Items;
// ... and we can read the value set to Foo's ApplicationId
var actualAppId = actualFoo.ApplicationId;
}
}

Invoke method from base class using reflection

I implemented generic repository pattern and unitofwork. I used basic patterns and they work great. In project I have requirement which says, every table has several fields which contains long, really long text, and user should have ability chose and open any of it. As each field named differently i decided to use power ov generics with reflection, to write method which resieves table name and field name and returns it.
Method, in generic Repository class, i wrote looks like this, it seems work properly
public interface IRepository<T> where T : class
{
//other methods
string GetPropertyByName(int id, string property);
}
public class Repository<T> : IRepository<T> where T : class
{
// other methods. add, edit, delete...
public string GetPropertyByName(int id, string property)
{
T model = this.Get(id);
var obj = model.GetType().GetProperty(property).GetValue(model, null);
return obj != null ? obj.ToString() : null;
}
}
I creted model classes for tables with help EF. Some tables binds directly genric repository, while other have separate interface and its implementation, as they require additional method. Example:
public interface ICompanyRepo : IRepository<COMPANY>
{
//some methods
}
public class CompanyRepo : Repository<COMPANY>, ICompanyRepo
{
//implementations of interface methods
}
And UOW implementation:
public interface IUnitOfWork
{
ICompanyRepo Company { get; }
IRepository<CURRENCY> Currency { get; }
}
public class UnitOfWork : IUnitOfWork
{
static DBEntities _context;
private UZMEDEXPORTEntities context
{
get
{
if (_context == null)
_context = new DBEntities();
return _context;
}
}
public UnitOfWork()
{
_context = context;
Company = new SP_CompanyRepo();
Currency = new Repository<CURRENCY>();
}
public ICompanyRepo Company { get; private set; }
public IRepository<CURRENCY> Currency { get; private set; }
}
I have problem on invoking GetPropertyByName() method in business layer.
I tried this:
public string GetHistory(string tableName, string fieldName, int id)
{
var prop = unitOfWork.GetType().GetProperty(tableName);
MethodInfo method;
method = prop.PropertyType.GetMethod("GetPropertyByName"); //try to find method
if(method == null) //if method not found search for interface which contains that method
method = prop.PropertyType.GetInterface("IRepository`1").GetMethod("GetPropertyByName");
var res = method.Invoke(prop, new object[] { id, fieldName });
return (string)res;
}
Which returns System.Reflection.TargetException. As I understood the problem is whith unitofwork implementation. In my invoke method "prop" is type of interface (ICompanyRepo), but invoke's target should be interface implementation class, in this case "CompanyRepo".
I could not find how to identify type of implementetion class, and solve this problem. Any help is appropriated
I am not sure that this is best option, but problem solved with use of ToExpando() extension given here. With this extension i could loop throw all properties of unitofwork and find required property by its name.
var propValue = unitOfWork.ToExpando().Single(x => x.Key == prop.Name).Value;
var res = method.Invoke(propValue, new object[] { id, fieldName });
Now method is invoking properly. May be there is cleaner solution, and I still hope to find this. For now i am going to use this solution, and just realised that I must read and practice a lot about reflections, dynamics and generics.
P.S Special thanks to Alexei for important notes and advices

Custom Attributes with NSubstitute

I'm currently mocking out an Interface with NSubstitute, which is basically a representation of a class with two properties and one method.
LoginViewModel = Substitute.For<ILoginViewModel>();
The mocked out interface is instantiated, then passed into a method which reflects upon it to get all the custom attributes.
LoginViewModel.Username = "User1";
LoginViewModel.Password = "Password1";
Each of the properties on the concrete implementation of the interface has a single custom attribute, however when reflected, the compiler shows no custom attributes.
[CustomRequired]
public string Username { get; set; }
[CustomRequired]
public string Password { get; set; }
Testing this without NSubstitute works. My question is: Does NSubstitute strip out Custom Attributes? Or is there a way to allow them through?
I don't know too much about custom attributes, so it is worth double checking the information in my answer.
First, NSubstitute does strip out some specific attributes, but not attributes in general. (Aside: NSubstitute uses Castle DynamicProxy to generate the proxy types, so to be more accurate NSubstitute asks Castle DP to strip these out. :) )
Secondly, if the attributes are declared on an interface they will not flow on to the class. They will however be available via the interface type itself. They will also be available if declared on a class and on substitutes for that class (provided the attribute is not configured explicitly to prevent being inherited):
public class MyAttribute : Attribute { }
public interface IHaveAttributes {
[My] string Sample { get; set; }
}
public class HaveAttributes : IHaveAttributes {
[My] public virtual string Sample { get; set; }
}
public class NoAttributes : IHaveAttributes {
public virtual string Sample { get; set; }
}
[Test]
public void TestAttributes()
{
// WORKS for class:
var sub = Substitute.For<HaveAttributes>();
var sampleProp = sub.GetType().GetProperty("Sample");
var attributes = Attribute.GetCustomAttributes(sampleProp, typeof(MyAttribute));
Assert.AreEqual(1, attributes.Length);
// WORKS directly from interface:
var sampleInterfaceProp = typeof(IHaveAttributes).GetProperty("Sample");
var attributes2 = Attribute.GetCustomAttributes(sampleInterfaceProp, typeof(MyAttribute));
Assert.AreEqual(1, attributes2.Length);
// Does NOT go from interface through to class (even non-substitutes):
var no = new NoAttributes();
var sampleProp2 = no.GetType().GetProperty("Sample");
var noAttributes = Attribute.GetCustomAttributes(sampleProp2, typeof(MyAttribute));
Assert.IsEmpty(noAttributes);
}

C# Moq Class with Interface

I tried to make a unit-testing of a class User
I tried to do it with an interface, but I did not understand exactly what is and if it is the correct way to do the test, so:
My Class User
public class User : IUser
{
public int id { get; private set; }
public string username { get; set; }
public IUser user;
public User(IUser userI) // constructor with interface
{
user = userI;
}
public virtual bool MyFunction(string test)
{
if(test=="ping")
return true;
else
return false;
}
}
My Interface IUser
public interface IUser
{
int id { get; }
string username { get; set; }
}
And then my Unit-test
[TestFixture]
public class MoqTest
{
[Test]
public void TestMyFunction()
{
var mock = new Mock<IUser>();
User user = new User(mock.Object);
var result = user.MyFunction("ping");
Assert.That(result, Is.EqualTo(true));
}
}
The test result is correct and actually returns true, but do not understand the way of using the interface.
Basically by mocking you create some kind of a dummy-implementation for that interface. So when calling Mock<IUser>() the compiler generates an anonymous class that implements the interface IUser and returns a new instance of this class. Now when creating your User-object you inject that dummy-object. The mocked object has no behaviour, all its members are set to to their default-value, it is only guaranteed that theay are set to anything. You can also change the values your members return but that won´t affect your example.
This way you can test the method you´re interested in without having to implement any external dependeines. This can be necessary because you have currently no working instance for the IUSer-interface and implement it later or because its initialization is quite heavy and you want to avoid initialize it within your tests (think of some database-logic included that does not affect your actual test, but would be needed to run the test).
In your case you could even use new User(null) as the method to be tested does not rely on an instance of that interface at all. So you won´t even have to mock it at all.

How to assign a mocked object to a object in controller?

I have a controller which contains a business class that internally has dependencies to a datahandler. For testing that business class I need to mock the datahandler. After setup, I am assigning the business class' datahandler with the mocked datahandler. But while debugging, the business class' datahandler is showing null , I know that I should use the constructor to inject the mocked object.But is it possible to do it without using any constructor injection ?Can any body help me with this?
my business class:
public class FooBusiness
{
public static BarDataHandler _barDatahandler = new BarDataHandler();
...
}
Test class:
public class FooBusinessTest
{
...
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x=>x.Search(It.IsAny<int>).Returns(1);
...
FooBusiness _fooBusiness = new FooBusiness();
FooBusiness._barDatahandler = _mockedBarDataHandler.Object;
//Act
...
}
}
As I mentioned, there are multiple ways to achieve your needs.
Personally I like Shyju's answer more (Constructor Injection), but if you can't change the constructor, you can still change the implementation afterwards by setting the property:
business class:
public class FooBusiness
{
private IBarDataHandler _barDatahandler = new BarDatahandler();
public IBarDataHandler BarDatahandler
{
get { return _barDatahandler; }
set { _barDatahandler = value; }
}
public int Search(int a)
{
return _barDatahandler.Search(a);
}
}
Test class:
public class FooBusinessTest
{
_mockedBarDataHandler = new Mock<IBarDataHandler>(){CallBase:true};
public FooTestMeth()
{
//Arrange
_mockedBarDataHandler.Setup(x => x.Search(It.IsAny<int>).Returns(1);
FooBusiness fooBusiness = new FooBusiness();
fooBusiness.BarDatahandler = _mockedBarDataHandler.Object;
//Act
}
}
If you worry about to refactor the implementation, it is better to setup all the tests first. After that you can refactor with a safer feeling :)
You need to inject your dataHandler dependency to FooBusiness
You need to extract an interface for your BarDataHandler if one does not exist.
interface IBarDataHandler
{
string GetUserToken(int id);
}
public class BarDataHandler : IBarDataHandler
{
public string GetUserToken(int id)
{
// to do :read from db and return
}
}
And add a constructor to FooBusiness class which accepts an implementation of IBarDataHandler.
public class FooBusiness
{
IBarDataHandler barDataHandler;
public FooBusiness(IBarDataHandler barDataHandler)
{
this.barDataHandler=barDataHandler
}
public string GetUserToken(int id)
{
return this.barDataHandler.GetUserToken(id);
}
}
You can use any one of the dependency injection frameworks like Unity/Ninject/StructureMap to resolve your concrete implementation when your app runs.
You can use any mocking framework like Moq to mock the fake implementation of IBarDataHandler in your unittests.

Categories