So I have a class whose constructor downloads some xml and reads it into properties for the class to work with. I'm instantiating this class a couple of times and this time-consuming job is done three times in exactly the same manner. Could I avoid it somehow (I guess with a static method/properties)? My class should only once go get the properties and then every instance could use them. I feel I should put the code out of my constructor in a static function, but how it's done exactly, I don't know, since I always get errors.
class MyClass {
protected $xml_file;
protected $xml_derived_array;
public function __construct($param1, $param2, $param3) {
//get xml_file and make xml_derived_array with it
//do some other stuff with parameters and properties such as $xml_derived_array
}
}
Should become something like: (but how should I call the static properties in my __construct and how should I set the properties in the static function?)
class MyClass {
protected static $xml_file;
protected static $xml_derived_array;
protected static function get_xml() {
//get xml_file and make xml_derived_array with it (?how exactly?)
}
public function __construct($param1, $param2, $param3) {
self::get_xml();
//do some other stuff with parameters and properties such as $xml_derived_array (?how exactly?)
}
}
Edit
This is how it is now working:
class MyClass {
protected static $xml_file;
protected static $xml_derived_array = array();
public function __construct($param1, $param2, $param3) {
if (!self::$xml_file) {
self::$xml_file = simplexml_load_file('xml_file.xml');
self::$xml_derived_array[0] = self::$xml_file->title;
}
echo self::$xml_derived_array[0].$param1;
}
}
You don't need a static method. Just check if the property has a value in constructor and if not get the xml file and process it.
class MyClass {
protected static $xml_file;
protected static $xml_derived_array = array();
public function __construct($param1, $param2, $param3) {
if (! count(self::$xml_derived_array)){
//get xml_file and make xml_derived_array with it
//do some other stuff with parameters and properties such as $xml_derived_array
}
}
}
Related
When my very first unit test class is run, why is the Session class not available in setUpBeforeClass? After the first unit test class has finished, the session class is available in setUpBeforeClass.
Is there something I can do to make sure that Session is available in my first unit test?
<?php
class AATest extends TestCase
{
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
\Session::put('tenantId',100); // <-- this fails
\Session::put('userId',1100);
}
public function setUp()
{
parent::setUp();
\Session::put('tenantId',100); // <-- if removed from before class, this works.
\Session::put('userId',1100);
}
public function test1()
{
$tenantId = \Session::get('tenantId');
$userId = \Session::get('userId');
$this->assertEquals(100,$tenantId);
$this->assertEquals(1100,$userId);
}
}
I have a model class witch basically is the fields from a database table with getter and setters.
class RealEstate extends BaseModel implements FilterProviderInterface
{
public $cityId;
public $stateId;
...
public $transferFields = array();
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
public function setTransferFields($transferFields)
{
$this->transferFields = $transferFields;
}
public function getTransferFields()
{
return $this->transferFields;
}
...
}
In my BaseTableGateway class I have a method save which takes this model object and extracts the data using get methods into an array.
$hydrator = new ClassMethods(false);
$model_data = $hydrator->extract($model);
I need the getTransferFields() method to bind the object to my form but I dont need it to be in the final array (be excluded while extracting).
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
This method does exactly what I want but only for 1 method. I can't find out how to filter more than 1 method. Does anyone know how this would be achieved?
Simply return a FilterComposite object. The FilterComposite implements FilterInterface and is treated the same as the MethodMatchFilter.
For example:
public function getFilter()
{
$myFilters = new FilterComposite();
$myFilters->addFilter('someParam', new MethodMatchFilter('getSomeParam'));
$myFilters->addFilter('someOtherParam', new MethodMatchFilter('getSomeOtherParam'));
return $myFilters;
}
I have a Page which consist of AddPage.xaml and AddPage.xaml.cs. I want to create a generic class AddPage which extends from PhoneApplicationPage to outsource some repetitive code like Save or Cancel.
If I change the base class from PhoneApplicationPage to my new generic class, I get this error: Partial declarations of 'AddPage' must not specify different base classes.
To accomplish this you need to do the following.
First, create your base class
public class SaveCancelPhoneApplicationPage : PhoneApplicationPage
{
protected void Save() { ... }
protected void Cancel() { ... }
}
Then, your AddPage needs to be modified to inherit from the base class. The main places this is needed is within the code (AddPage.xaml.cs) AND within the xaml
Code:
public partial class AddPage : SaveCancelPhoneApplicationPage { ... }
Xaml:
<local:SaveCancelPhoneApplicationPage
x:Class="MyPhone.Namespace.AddPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyPhone.Namespace"
<!-- other xaml elements -->
</local:SaveCancelPhoneApplicationPage>
UPDATE: Info added based on comments
If you need to have generic like functionality and you must use the Page to do this (rather than a ViewModel) then you can still do this using generic methods
public abstract class SaveCancelPhoneApplicationPage : PhoneApplicationPage
{
protected override void OnNavigatedTo(blaa,blaa)
{
var obj = CreateMyObject();
obj.DoStuff();
}
// You should know what your objects are,
// don't make it usable by every phone dev out there
protected MyBaseObject MyObject { get; set; }
protected T GetMyObject<T>() where T : MyBaseObject
{
return MyObject as T;
}
}
public class AddPage : SaveCancelPhoneApplicationPage
{
public AddPage()
{
MyObject = new MyAddObject();
}
}
In order to outsource some functions you just declare some add class which does the common work. Having another page doesn't do that work.
public class Add
{
public bool SaveContent(string filename, string content)
{
....//some content
return true;
}
public string ViewContent(string filename)
{
string content="";
.....
return content;
}
}
Add this part of code where you thought it is redundant.
Add obj=new Add();
obj.SaveContent("myfile.txt","Hello.This is my content.");
string content("myfile.txt");
Tell me if this is what you intend or not.
I am using Ninject and the MVC3 extension installed with nuget. My kernel setup code is in the App_Start/NinjectMVC3.cs file. Everything works great in controllers, but I can't figure out how to (properly) bind interfaces in the Global.asax.cs MvcApplication code.
I ended up using a hack (creating a public NinjectMVC3.GetKernel() method that returns bootstrap.kernel). However, that will be deprecated, and there must be a proper way to do this that I am not seeing.
Here is my code:
public class LogFilterAttribute : ActionFilterAttribute
{
private IReportingService ReportingService { get; set; }
public LogFilterAttribute( IReportingService reportingService )
{
this.ReportingService = reportingService;
}
...
}
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters( GlobalFilterCollection filters )
{
filters.Add( new HandleErrorAttribute() );
filters.Add( new LogFilterAttribute() );
}
...
protected void Application_Start()
{
...
RegisterGlobalFilters( GlobalFilters.Filters );
// NOTE hack:
var kernel = NinjectMVC3.GetKernel();
var logger = kernel.Get<ILogger>();
var bw = new BackgroundWork(logger);
Application["BackgroundWork"] = bw;
bw.Start();
}
}
There are two interfaces I am interested in. The first is just binding an object to a Global variable (the ILogger for the BackgroundWork).
And the second is for an ActionFilter. I read http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/, but I don't see how it plugs into the actual registration (filter.Add).
I don't want to use the Property Inject if I can avoid it.
Any thoughts on the proper way to do this?
Thanks
MVC 3 introduces the DependencyResolver which is populated into a singleton, and the Ninject extension supports it. You could use that in your MvcApplication class if you need it:
protected void Application_Start()
{
// ...
var logger = DependencyResolver.Current.GetService<ILogger>();
}
Now I should point out that it is unnecessary to do this with action filters. In Ninject.MVC3 you are supposed to use the BindFilter syntax, like so:
// Declare empty attribute
public class MyFilterAttribute : FilterAttribute { }
// Dependency module
public class MyModule : NinjectModule
{
public override void Load()
{
// Other bindings
// ...
this.BindFilter<MyActionFilter>(FilterScope.Action, 1)
.WhenControllerHas<MyFilterAttribute>();
}
}
Note that you have to use this because BindFilter is an extension method, and you also have to reference the Ninject.Web.Mvc.FilterBindingSyntax namespace.
New to the world of TDD and I have soon find out that mocking at times is not as easy.
We are using MOQ at work so I need to learn how to do this using moq
I have some code using the command pattern and works a treat.However If were to test drive it I would not know how to do it implementing the code below.
I have done the following
Created BaseToolStripMenuItem:ToolStripMenuItem and added a Command Property (see below)
Created a windows form and added a menuStrip with 2 item Open and Exit
In the form I just add to map the command to a button and all works a treat.
I would like to change the code so that I can UnitTest using Moq but cannot see how???
Can you help?
Any suggestions?
Thanks a lot!!
public interface ICommand
{
void Execute()
}
public abstract class BaseCmd :ICommand
{
protected ProcessMenuCommand ProcessCommand;
protected MenuCommandFactory Factory;
protected BaseCmd(ProcessMenuCommand processMenuCommand, MenuCommandFactory cmdfactory)
{
ProcessCommand = processMenuCommand;
Factory = cmdfactory;
}
abstract public void Execute();
}
public class BaseToolStripMenuItem : ToolStripMenuItem
{
public BaseToolStripMenuItem()
{
Click += MenuItemClick;
Command = null;
}
public BaseCmd Command { get; set; }
private void MenuItemClick(object sender, EventArgs args)
{
if (Command != null) Command.Execute();
}
}
public class MenuCommandFactory
{
private readonly ProcessMenuCommand _processMenuCommand;
public MenuCommandFactory(ProcessMenuCommand processMenuCommand)
{
_processMenuCommand = processMenuCommand;
}
public OpenFileCmd OpenFile()
{
return new OpenFileCmd(_processMenuCommand,this);
}
public ExitCmd Exit()
{
return new ExitCmd(_processMenuCommand, this);
}
}
public class OpenFileCmd:BaseCmd
{
public OpenFileCmd(ProcessMenuCommand processMenu,MenuCommandFactory menuCommandFactory)
:base(processMenu,menuCommandFactory)
{
}
public override void Execute()
{
ProcessCommand.OpenFile();
}
}
public class ProcessMenuCommand
{
public void OpenFile()
{
MessageBox.Show("Open a file");
}
public void Exit()
{
MessageBox.Show("Exiting");
}
}
public class ExitCmd:BaseCmd
{
public ExitCmd(ProcessMenuCommand processMenu, MenuCommandFactory menuCommandFactory)
:base(processMenu,menuCommandFactory)
{
}
public override void Execute()
{
ProcessCommand.Exit();
}
}
//In the form
public partial class Form1 : Form
{
private ProcessMenuCommand menuCommandProcessor;
private MenuCommandFactory factory;
public Form1()
{
InitializeComponent();
// Created editor and factory.
menuCommandProcessor = new ProcessMenuCommand();
factory = new MenuCommandFactory(menuCommandProcessor);
// Get concrete command objects from factory and assign to corresponding menu items and tool strip buttons.
tsOpen.Command = factory.OpenFile();
tsExit.Command = factory.Exit();
}
}
However If were to test drive it I would not know how to do it implementing the code below
The idea about TDD is that it drives you towards an implementation. There are many implementations you could never arrive at using TDD, so your question doesn't really make much sense.
Try to write some tests that drive you towards your goal without having a preconceived image of the solution at which you wish to arrive. It will often turn out that you end up at an entirely different (and better) place than what you originally thought.
A simple Novice Rule: no abstract classes. Try designing again with only interfaces and concrete classes. You'll notice it's easier to test-drive the result.
As for "how to TDD a Command object", a Command is just a class that provides a single action. Test-drive it the same way you would test-drive any method, except you name the method Execute().