Help in using Moq - moq

I have a class that takes in a db factory.
public class ArticleManager
{
private IDAOFactor _factory;
public ArticleManager(IDAOFactory factory)
{
this._factory = factory;
}
}
Using moq, how do I create an instance of ArticleManager?
I tried:
var mockFactory = new Mock<IDAOFactory>();
ArticleManager am = new ArticleManager(mockFactory);
But that isn't compiling.

mockFactory is a proxy class for moq. To expose the ArticleManager object instance within the mock, you'd use mockFactory.Object like so:
var mockFactory = new Mock<IDAOFactory>();
ArticleManager am = new ArticleManager(mockFactory.Object);

Related

How to configure dependency injection for self hosted MVC 4 API controllers

After checking all the similar questions on SO, my issue persists so I'm opening a new question for it.
I have a unit test that references anther project that contains a MVC 4 ApiController which has a constructor for dependency injection.
public class DataController : ApiController
{
public DataController(IRepository repository){}
}
In my test, I'm using Microsoft.Extensions.DependencyInjection and have the following setup:
// Note: this redundant type access is necessary to load controllers from a different assembly,
// see https://stackoverflow.com/a/11758025/1468097
var type = typeof(DataController);
var services = new ServiceCollection().AddSingleton<IRepository>(new ImMemoryRepository());
var httpConfiguration = new HttpConfiguration
{
DependencyResolver = new DependencyResolver(services.BuildServiceProvider()),
IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
httpConfiguration.Routes.MapHttpRoute("Default", "{controller}/{action}");
httpConfiguration.DependencyResolver = new DependencyResolver(services.BuildServiceProvider());
var httpServer = new HttpServer(httpConfiguration);
var client = new HttpClient(httpServer);
var response = await client.GetAsync("http://whatever/data/getdata?id=000");
and I have a fairly barebone implementation of the dependency resolver as nested private class inside the test class:
private class DependencyResolver : IDependencyResolver
{
private readonly ServiceProvider _serviceProvider;
public DependencyResolver(ServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
public void Dispose() => _serviceProvider.Dispose();
public object GetService(Type serviceType) => _serviceProvider.GetService(serviceType);
public IEnumerable<object> GetServices(Type serviceType) => _serviceProvider.GetServices(serviceType);
public IDependencyScope BeginScope() => new Scope(_serviceProvider.CreateScope());
private class Scope : IDependencyScope
{
private readonly IServiceScope _scope;
public Scope(IServiceScope scope) => _scope = scope;
public void Dispose() => _scope.Dispose();
public object GetService(Type serviceType) => _scope.ServiceProvider.GetService(serviceType);
public IEnumerable<object> GetServices(Type serviceType) => _scope.ServiceProvider.GetServices(serviceType);
}
}
The response I get from the test is a 500 server error saying
Type 'Mvc.DataController' does not have a default constructor
It seems I'm doing what all the others are doing for dependency injection in MVC 4, even for this question that has a very similar symptom.
Am I missing something obvious here?
Update
I've tried NinjectResolver comes down to the same problem:
var kernel = new StandardKernel();
kernel.Bind<IRepository>().ToConstant(new InMemoryRepository());
var httpConfiguration = new HttpConfiguration
{
DependencyResolver = new NinjectResolver(kernel)
};
I figured this out.
The key is that you also need to add the controller you are hitting in your dependency configuration.
In my case, I just need to add:
var services = new ServiceCollection();
// This is what was missing.
services.AddTransient<DataController>();
Taken from here (although I'm not using OWIN at all): How to add Microsoft.Extensions.DependencyInjection to OWIN Self-Hosted WebApi
Another example using Autofac:
var builder = new ContainerBuilder();
// You need to register the assembly that contains your controller.
builder.RegisterApiControllers(typeof(DataController).Assembly);
Taken from here: Dependency injection not working with Owin self-hosted Web Api 2 and Autofac

Configuring Automapper in a .NET Core Console App with a data library?

I'm very new to AutoMapper, .NET Core and DI - although I am familiar with .NET Framework. I'm struggling to get AutoMapper to work in an app I've built. The app is a console app, which has a data library attached to it.
I've tried to configure AutoMapper in the Main() method of the console app - because as I understand it you need to configure it at the startup point of the app? I'm then creating an instance of a class in the data library which then in turn creates an instance of the Mappers class where I do all my mappings. I'm not sure if I've setup everything correctly and if I have I'm not sure what to pass to the constructor in the Mappers class to make it all work?
Console:
class Program
{
static void Main()
{
var services = new ServiceCollection();
services.AddAutoMapper(typeof(AutoMapping));
Learner learner = new Learner();
}
}
class AutoMapping : Profile
{
public AutoMapping()
{
CreateMap<LearnerDTO, LearnerModel>();
}
}
Learner Class (in my DataLibrary):
public class Learner
{
public string GetLearner()
{
Mappers mappers = new Mappers(); //This Mappers instance is underlined red
LearnerDTO learnerDTO = JsonFactory.LoadJson();
LearnerModel learnerModel = mappers.LearnerDTOtoLearnerModel(learnerDTO);
}
}
Mappers Class:
public class Mappers
{
private IMapper _mapper;
public Mappers(IMapper mapper)
{
_mapper = mapper;
}
public LearnerModel LearnerDTOtoLearnerModel(LearnerDTO learnerDto)
{
LearnerModel model = _mapper.Map<LearnerModel>(learnerDto);
return model;
}
}
Firstly, I would like some comment on whether I've configured AutoMapper correctly and in the right place? And secondly, if it all looks fine, what do I need to pass into the Mappers constructor from the Learner class when creating an instance?
If using dependency injection, then the classes should be refactored to allow for that using service abstractions and explicitly dependency principle via constructor injection.
Learner class and abstraction
public interface ILearner {
string GetLearner();
}
public class Learner : ILearner {
private readonly IMappers mappers;
public Learner(IMappers mappers) {
this.mappers = mappers;
}
public string GetLearner() {
LearnerDTO learnerDTO = JsonFactory.LoadJson();
LearnerModel learnerModel = mappers.LearnerDTOtoLearnerModel(learnerDTO);
}
}
Mappers class and abstraction
public interface IMappers {
LearnerModel LearnerDTOtoLearnerModel(LearnerDTO learnerDto);
}
public class Mappers : IMappers {
private readonly IMapper _mapper;
public Mappers(IMapper mapper) {
_mapper = mapper;
}
public LearnerModel LearnerDTOtoLearnerModel(LearnerDTO learnerDto) {
LearnerModel model = _mapper.Map<LearnerModel>(learnerDto);
return model;
}
}
Everything should then be registered with the dependency container, which will be used to resolve the services and perform the desired function.
Console
class Program {
static void Main() {
var services = new ServiceCollection();
services.AddAutoMapper(typeof(AutoMapping));
//use the lifetime that suits your needs
//but for this example I am using transient
services.AddTransient<ILearner, Learner>();
services.AddTransient<IMappers, Mappers>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
ILearner learner = serviceProvider.GetRequiredService<ILearner>();
//...
}
}

How do I pass an id variable to a class which has dependency injection Symfony 3.4

I have class that uses Dependency Injection, with two other classes, this works fine. But I want to then instantiate the Merchant class in a controller and pass an id . Thing I don't get is the constructor is expecting more values 'CurrencyConverter' and 'TransactionTable' so how can I complete the code ? ?, which I don't need to pass. So I'm not clear how to make it work, thanks
Model Class
namespace TransactionBundle\Model;
class Merchant
{
public $_transactions;
public $_currencyConverter;
public $_id;
public function __construct($id,CurrencyConverter
$currencyConverter,TransactionTable $transactions)
{
$this->_transactions = $transactions;
$this->_currencyConverter = $currencyConverter;
$this->_id = $id;
}
public function getTransactions() {
$this->_currencyConverter->convert();
$this->_transactions->getData();
}
}
trying to instantiate in the controller
$merchant = new Merchant(2,?,?);
$results = $merchant->getTransactions();
If the class has a dependency on something that is not in the container, then the class cannot be loaded from the container.
Either pass the dependencies yourself in the controller:
$merchant = new Merchant(2, $currencyConverter, $transactions);
Or use a factory service in the container:
class MerchantFactory {
private $currencyConverter;
private $transactions;
// constructor omitted for brevity
public function getMerchantForId($id) {
return new Merchant($id, $this->currencyConverter, $this->transactions);
}
}
Then in your controller, depend on the factory:
$merchant = $this->merchantFactory->getMerchantForId(2);

#Autowired object initialization and scope

As far my knowledge #Autowired object is initialized when the application start and this is handled by spring and scope will depends on what we specify in bean.xml and #Autowired object are available right before they are used actually in the code.
My question is in below code I want that for every call to SAController class a new SuperAdminDetailsManager object should be created. So I configure scope = "prototype" is that correct so that for every call to controller a new SuperAdminDetailsManager object will be created.
Controller Class
#Controller
public class SAController {
#Autowired
private SuperAdminDetailsManager superAdminDetailsManager;
private static final Logger logger = LoggerFactory.getLogger(SAController.class);
private ApplicationContext context = null;
#RequestMapping(value = "/sadminlogin", method = RequestMethod.GET)
public String redirectLogin(ModelMap map) {
map.addAttribute("superAdmin", new SuperAdmin());
return "sa_login";
}
public void setSuperAdminDetailsManager(
SuperAdminDetailsManager superAdminDetailsManager) {
this.superAdminDetailsManager = superAdminDetailsManager;
}
}
beans.xml Configuration
context = new ClassPathXmlApplicationContext("beans.xml");
<bean id="superAdminManager" class="com.serviceimpl.SuperAdminDetailsManagerImpl" scope="prototype"></bean>
One more question when I can get the object using ClassPathXmlApplicationContext why do I need autowired
Object using ClassPathXmlApplicationContext
superAdminDetailsManager = (SuperAdminDetailsManager )context.getBean("superAdminManager");

controller mvc3 unit test

How to write unit test for
public ActionResult Details()
{
EmployeeDTO employee = this.EmployeeService.GetLoggedInEmployee();
EmployeeModel model = assembler.ToEmployeeModel(employee);
model.Title = GetEmployeeNameTitle(employee);
model.Controller = "LoanProcessor";
model.SelectedTab = MainNavTabs.LoanProcessor;
return View(model);
}
I have no idea how to solve it.
To make your code testable, you should inject dependencies to controller (it's not clear from this piece of code if you passing dependencies to controller, or instantiate them directly). Also you should make your controller to depend on abstractions (preferably interfaces) rather than concrete implementations.
EmployeeService should implement this interface:
public interface IEmployeeService
{
EmployeeDTO GetLoggedInEmployee();
// other methods of service
}
Then you make your controller depending on abstraction (only one dependency shown here for sample):
public class FooController : Controller
{
private IEmployeeService _employeeService;
public FooController(IEmployeeService employeeService)
{
_employeeService = employeeService;
}
}
Now you can mock dependencies and start writing tests for controller (sample with NUnit and Moq):
[Test]
public void ShouldProvideEmployeeDetails()
{
// Arrange
EmployeeDTO bob = new EmployeDTO("Bob", 42);
Mock<IEmployeeService> employeeService = new Mock<IEmployeeService>();
employeeService.Setup(s = s.GetLoggedInEmployee()).Returns(bob);
FooController controller = new FooController(employeeService.Object);
// Act
var result = controller.Details() as ViewResult;
// Assert
EmployeeModel model = result.ViewData.Model;
Assert.That(model.Title, Is.EqualTo("Bob"));
Assert.That(model.Controller, Is.EqualTo("LoanProcessor"));
}
Then write code to pass this test.
You can read more on TDD here.

Resources