How to mock a Generic Abstract class - moq

Assuming I have an Interface IReportBuilderService and concrete class ReportBuilderService
e.g. public class ReportBuilderService : IReportBuilderService { }
I can start to mock this service with Moq as such
Mock<IReportBuilderService> _reportBuilderServiceMock = new Mock<IReportBuilderService>();
And mock expectations etc on the mock class, ok no problems.
Question: How do I mock the following method signature?
public abstract class ReportBuilder<TReport> where TReport : Report, new()
where a TReport is defined as
public class SomeReport : ReportBuilder<Report>, IMapper{}
And Report class is simply
public class Report { }
In the abstract class ReportBuilder there are a series of Property Get/ Sets, it is the value of these that I’m trying to fake/mock.
But I can’t begin to get the correct mock on this abstract class to start with
Hope this makes sense

Given that your abstract class looks like this:
public abstract class ReportBuilder<TReport> where TReport : Report, new()
{
public abstract Int32 SomeThing { get; set; }
}
there's no problem in mocking it at all:
var m = new Mock<ReportBuilder<Report>>();
m.SetupProperty(r => r.SomeThing, 19);
but note that all your properties have to be virtual or abstract.
So if this is not the case (and you can't or don't want to change this), you could either extract an interface from your base class and use this (if you're willing to change your code accordingly), or simply create a stub/mock by subclassing:
public class StubReportBuilder : ReportBuilder<Report>
{
public override Int32 SomeThing { get { return 42; } set { } }
}

Related

Error in CreateInstance() while dynamically creating object of concrete type in Factory Pattern

I am actually new to design patterns and trying to implement factory pattern with .NET Core.
I tried to see couple of posts related to factory pattern and trying to implement it, I have added the concrete types in the config and reading it as dictionary in my code -
My Factory Interface -
public interface IEmpFactory
{
public BaseEmployee CreateEmployeeType<EmpType>()
where EmpType : BaseEmployee, new();
}
Implementation -
public class EmpFactoryImpl : IEmpFactory
{
public BaseEmployee CreateEmployeeType<EmpType>()
where EmpType: BaseEmployee, new()
{
return new EmpType();
}
}
Below are my services which are using the Factory as dependency -
public interface IEmpService
{
public string GetEmployeeBonus();
}
public class ContractEmpService : IEmpService
{
IEmpFactory _empFactory;
public ContractEmpService(IEmpFactory empFactory) =>
_empFactory = empFactory;
private BaseEmployee CreateMyEmployee() =>
_empFactory.CreateEmployeeType<ContractEmp>();
public string GetEmployeeBonus() =>
return CreateMyEmployee().GetBonus();
}
public class PermEmpService : IEmpService
{
private readonly IEmpFactory _empFactory;
public PermEmpService(IEmpFactory empFactory) =>
_empFactory = empFactory;
private BaseEmployee CreateMyEmployee() =>
_empFactory.CreateEmployeeType<PermEmp>();
public string GetEmployeeBonus() =>
CreateMyEmployee().GetBonus();
}
Added these concrete types in the config -
"ConfigurationProps": {
"EmpServices": {
"PermEmp": "SimpleFactoryWithoutSwitchCase.Service.PermEmpService",
"ContractEmp": "SimpleFactoryWithoutSwitchCase.Service.ContractEmpService"
}
}
Created the class to create a instance of the concrete type based on the type i.e, PermEmp or ContractEmp dynamically -
public class EmployeeTypeRouter : IEmployeeTypeRouter
{
private readonly ConfigurationProps _props;
public EmployeeTypeRouter(ConfigurationProps props)
{
_props = props;
}
public IEmpService GetInstance(string key)
{
string className = _props.EmpServices
.Where(k => k.Key.Equals(key)).FirstOrDefault().Value;
Type t = Type.GetType(className);
return (IEmpService)Activator.CreateInstance(t);
}
}
This is my calling method -
[HttpGet(Name = "GetEmployeeBonus")]
public string Get()
{
string type = "PermEmp";
IEmpService empService = _empRouter.GetInstance(type);
return empService.GetEmployeeBonus();
}
based on the type passed here i want to fetch the concrete type and call the method.
I am getting the error like this on CreateInstance method -
System.MissingMethodException: `Cannot dynamically create an instance of type 'SimpleFactoryWithoutSwitchCase.Service.PermEmpService'. Reason: No parameterless constructor defined.'
Which is very clear, but I don't want to create a parameterless constructor.
Since I am registering the dependencies in .NET Core, do I need to pass it again here? (which does not make sense for me)
Any help is really appreciated or if you feel I am doing something wrong please let me know.
Your EmployeeTypeRouter class tries to replicate the creation process that your DI Container can do more eloquently. So instead of calling Activator.CreateInstance, forward the resolution to the DI Container.
This means the following things:
Register all known IEmpService at startup.
Resolve the expected type from the IServiceProvider from inside the EmployeeTypeRouter.
In other words, change the startup code to the following:
var dictionary = props.EmpServices
.ToDictionary(p => p.Key, p => Type.GetType(p.Value));
foreach (string pair in dictionary)
{
services.AddTransient(pair.Value);
}
services.AddTransient<IEmployeeTypeRouter, EmployeeTypeRouter>();
services.AddTransient<Func<string, IEmpService>>(sp =>
key => (IEmpService)sp.GetRequiredService(dictionary[key]));
And change EmployeeTypeRouter to the following:
public class EmployeeTypeRouter : IEmployeeTypeRouter
{
private readonly Func<string, IEmpService> _factory;
public EmployeeTypeRouter(Func<string, IEmpService> factory)
{
_factory = factory;
}
public IEmpService GetInstance(string key) =>
_factory.Invoke(key);
}
In the previous code snippet, EmployeeTypeRouter makes use of the Func<string, IEmpService> delegate, which functions as factory. Under the covers the delegate calls back into the IServiceProvider.
There are of course several ways to skin a cat. You could also move some of the startup logic into EmployeeTypeRouter, or even remove the IEmployeeTypeRouter altogether and let application code depend directly on Func<string, IEmpService> delegate.

In 2 different ASP.Net Core API Controllers, how to ensure same endpoints are defined?

I have a requirement to have 2 data api's both of which should have same methods or endpoints to be implemented.
For example, we can have an interface to make sure, two classes will have same functions. Otherworldly, you define the contract.
public interface ITest
{
void Foo();
}
public class Test : ITest
{
public void Foo()
{
// Some logic
}
}
public class OtherTest : ITest
{
public void Foo()
{
// Some other logic
}
}
Similarly, I want controllers which will have routes and methods like below. Say in one a new action is added, the code should enforce it in the other controller.
DemoController
-- GET demo/api/action1
-- GET demo/api/action2
TestController
-- GET test/api/action1
-- GET test/api/action2
How to achieve this?
Well, you've sort of answered your own question, really. If you want to ensure that the same methods are implemented on multiple classes, that is what interfaces are for. You just make each controller implement the same interface and you're good to go.
As for ensuring a similar routing structure, you can use inheritance for that. Define a base abstract controller class. You can either choose to implement your interface here, and "implement" the required methods as abstract. Any derived class will be forced to implement any abstract methods on the base class, so it has the same effect as an interface. That technically means you can forgo the interface, if you want, and just rely on the base class forcing the implementation. Up to you. Then you can apply route attributes to your abstract methods like so:
[Route("[controller]/api")]
public abstract BaseApiController : ControllerBase
{
[HttpGet("action1")]
public abstract IActionResult Action1();
[HttpGet("action2")]
public abstract IActionResult Action2();
}
if you are dealing with different entities that requires similar business logic, you can create generic base controller and inject your common dependencies as well:
[Route("api/[controller]")]
[ApiController]
public class GenericBaseController<T> : ControllerBase where T : class
{
private readonly ILogger _logger;
public GenericBaseController(ILogger<GenericBaseController<T>> logger) {
_logger = logger;
}
[HttpGet("get")]
public IActionResult Get()
{
//...
}
[HttpPost("post")]
public IActionResult Post(T value)
{
//...
}
}
then you can extend the generic controller :
[Route("api/[controller]")]
[ApiController]
public class MyFirstController : MyFirstController<FirstModel>
{
public GenericBaseController(ILogger<MyFirstController> logger) : base(logger)
{
}
}
another one:
[Route("api/[controller]")]
[ApiController]
public class MySecondController : GenericBaseController<SecondModel>
{
public MySecondController(ILogger<MySecondController> logger) : base(logger)
{
}
}
You don't have to re-create the methods for each inherited controller if it is the same logic, or you may extend any of it if you need:
[Route("api/[controller]")]
[ApiController]
public class MyThirdController : GenericBaseController<ThirdModel>
{
public MyThirdController(ILogger<MyThirdController> logger) : base(logger)
{
}
[HttpPost("post")]
public IActionResult Post(ThirdModel value)
{
// do some logic...
return base.Post(value);
}
}

any work around to allow for an action result to accept a Abstract class as parameter

I have different configurations all inheriting from a base configuration that are customized in forms. I want all of these to be handled by a single action result.
[HttpPost]
public IActionResult Register(AbstractBaseConfig config)
{
...do some logic...
return View("../Home/Index");
}
However, this is not possible because you cannot base in abstract classes as a parameter to an action result. Is there any work around for this so I don't need a seperate action result for each configuration? (I still want each configuration to be it's own class, I only need access to the base class methods in the action result logic).
Basically you can't, and the reason is that MVC will try to do new AbstractBaseConfig() as part of the Data Binding process (which parses the URL or the Form Post and puts the results in a concrete object). And by definition, doing new AbstractBaseConfig() is impossible for an abstract class.
It also makes sense for other reasons, I will explain why.
You seem to expect that MVC can determine the class from the parameters that are being passed in. That is not how it works, in fact the opposite is true: the Action Method has to specify the exact class, and then the Binder will instantiate that exact class and try to bind its properties.
Suppose you had this:
public abstract class Thing { public int ID { get;set; } }
public class NamedThing : Thing { public string Name { get;set; } }
public class OtherThing : Thing { public string Name { get;set; } }
and suppose it would be allowed to use:
public IActionResult Register(Thing thing)
then what would you expect to be in thing after Data Binding: a Thing object with only the ID set? Or one of the other object types, with Name set, but how would MVC ever be able to know which class you meant?
So for all these reasons, this is not possible.
You could have a base class inherit the abstract class and all your classes inherit from that base class whilst having that base class as your parameter
Take for example
public abstract class ABase
{
public void stuff()
{
var stuff = string.Empty;
stuff = "hello";
}
public virtual void otherstuff()
{
var stuff = string.Empty;
stuff = "hello";
}
}
public class Base : ABase
{
//empty
}
public class Derived : Base
{
public void mystuff()
{
this.stuff();
}
public override void otherstuff()
{
// Custom code
}
}
public ActionResult Register(Base config)
{
}

Combining two identical sub classes

So I have two sub classes that extend different base classes in Flex how can I combine these so that I am not repeating myself.
Basically I have something like
public class A extends B {
// methods
}
public class C extends D {
// same methods as class A
}
any way to combine this so that I am not repeating the same code twice.
Favor composition over inheritance
So, the question is, how should you compose the solution?
One possibility is to use Decorator pattern. This is essentially a wrapper around your existing Classes. To make this work, your Classes will probably need to implement an Interface that exposes whatever you'll need to do the job.
So something like:
public interface IFoo {
function get name():String;
function set name(value:String):void;
}
public class A extends B implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
_name = value;
}
}
public class C extends D implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
if (_value != _name) {
_name = value;
dispatchEvent(new Event('nameChanged'));
}
}
}
public class FooDecorator {
protected var _foo:IFoo;
public function FooDecorator(foo:IFoo) {
_foo = foo;
}
public function sayName():void {
trace('foo name is', _foo.name);
}
}
Another solution is to give both A and C member variables of a fifth type that encapsulate the behavior (like what Jeffry said, but I prefer to obey the law of Demeter where possible):
class NameSayer {
function sayName(name:String):void {
trace('foo name is', _foo.name);
}
}
then
public class A extends B {
public var name:String;
public var sayer:NameSayer;
//note that this method would be identical in both Classes
//but this is OK because the underlying logic is encapsulated
//and can be easily changed
public function sayName():void {
if (sayer) {
sayer.sayName();
}
}
}
I think many developers get too hung up on zealously following DRY and, as Jeffry says, this can cause other, worse, problems in your architecture. Which, if any, of these solutions is appropriate will depend on exactly what you're trying to accomplish.
You have two child classes (extending different parents) that implement the exact same methods.
public class B {}
public class D {}
public class A extends B {
// methods
m1();
m2();
...
}
public class C extends D {
// same methods as class A
m1();
m2();
...
}
Now lets make some points about it.
In assigning a method to a class, the basic idea is that, that method or behaviour really belongs to that class - it is really a property of that class or type. For example, breathing for Animal. When this is the case, the behaviour is tied to class state (or data, or attributes, or variables). If a method does not access the class variables in any ways, then, that method may not belong there. At least it is the general rule.
Now, in your case, you have m1(), m2(), ... methods that appear in two different classes. This raises the possibility that they may not be really tied to the state of those classes. If so, then the better solution is to completely remove them into a new class.
If you do so,
You will also get rid of two classes, A and C, which now exist only for this purpose.
You get rid of two inheritance relationships. This makes you code much simpler.
And, you will achieve your objective of not repeating your self.
--
//Parent classes (child classes are now gone)
public class B {}
public class D {}
--
// Your new class
public class X {
// methods that previously were in A and C
m1();
m2();
...
}
Although, I have mixed feelings about its use; you can use the include directive.
Create a file, like this, named sharedMethods.as (or whatever you want). This is not a real class; it just includes code snippets:
public var mySharedMethod(mySharedMethodArguments:ArgumentType):void{
// do something
}
Then you can include it in your your other classes:
public class A extends B {
include "sharedMethods.as";
}
public class C extends D {
include "sharedMethods.as";
}
The code from your include file will be compiled as part of Class A and Class C.
You could also put your shared code in another class and have an instance of that class in both A and C. Then you either have to write wrapper methods or drill down the calls sort of like this:aInstance.sharedCodeObject.sharedMethod();
My intuition is that if you run into this a lot; you may have a problem with the object model that needs some refactoring.

Hadoop Map output IOException when emitting subclass of a class defined in Configuration as an ouput

I have 3 simple classes:
public abstract class Container implements WritableComparable<Container> {} //empty
public class WeightedEdge extends Container { ... }
public class NodeWeightContainer extends Container { ... }
The Map phase was configured as such
JobConf createGraphPConf = new JobConf(new Configuration());
Job job = new Job(createGraphPConf);
...
createGraphPConf.setMapOutputValueClass(Container.class);
However I am receiving this error:
java.io.IOException: Type mismatch in value from map: expected org.hadoop.test.data.util.Container, recieved org.hadoop.test.data.WeightedEdge
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1018)
at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:591)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:33)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:19)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:435)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:371)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)
Why I can't return a subclass of a class that was defined in the configuration? Is there a way around it? The problem is that my Map phase has to emit two distinct object types.
You can not return a subclass of a class that was defined in the configuration because Hadoop explicitly checks class type specified in setMapOutputValueClass and the type it receives from Mappers.
It does so because it needs to serialize/deserialize objects you emit from mappers. When it performs deserialization it creates new object of type that is specified in setMapOutputValueClass call and then uses methods of WriteableComparable interface to fill newly created object with data.
To be able to emit different object types you may define container non-abstract class and place actual object and its type identifier inside
public enum ELEM_TYPE { WE, WECONTAINER }
public class Container implements WritableComparable<Container>
{
ELEM_TYPE type; //actual element type -
// WeightedEdge or NodeWeightContainer
object value;
//WritableComparable implementation
// that casts value to the appropriate type
}
public class WeightedEdge { ... }
public class NodeWeightContainer { ... }
I faced the same problem today. There is a Writable class org.apache.hadoop.io.GenericWritable which can be used to address this problem. You need to extend the class and implement an abstract method:
public class Container extends GenericWritable {
private static Class[] CLASSES = {
WeightedEdge.class,
NodeWeightContainer.class,
};
protected Class[] getTypes() {
return CLASSES;
}
}
public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
Now you can use the class Container as the output value type of your mapper.
Important: Your actual map output classes (WeightedEdge and NodeWeightContainer) must implement the Writable interface.

Resources