I have some 20+ TWebActionItems with associated OnAction event handlers:
procedure TWebModuleWebServices.WebModuleWebServicesTTLoginAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
on a TWebModuleWebServices = class(TWebModule). (Note: Sender is a TWebActionItem)
These handlers all have some identical local variables, 'initialization' and 'finalization' code.
I have managed to move some code to AfterDispatch and BeforeDispatch handlers for the TWebModuleWebServices.
If I want to move more common code, I would need store data in (object) variables in the BeforeDispatch (and access these variables in the OnAction handlers and AfterDispatch).
Since AfterDispatch and BeforeDispatch have the same Sender: TObject; Request: TWebRequest; Response: TWebResponse; parameters as the OnAction handlers, I'm thinking about writing a class helper for either TWebActionItem or TWebRequest.
Class helpers are not allowed to have data members ("E2169 Field definition not allowed after methods or properties"), but there is a trick with class vars/constructors/destructors.
In this article the author circumvents the fact that class vars are global by using a TDictionary:
TPanelHelper2 = class helper for TPanel
public
class var
MetaData: TDictionary<TPanel, string>; //store some strings - an example
procedure PutData(aData: string);
function ReadData: string;
class constructor SetUp;
class destructor TearDown;
end;
implementation
procedure TPanelHelper2.PutData(aData: string);
begin
MetaData.AddOrSetValue(Self, aData);
end;
function TPanelHelper2.ReadData: string;
begin
if MetaData.ContainsKey(Self) then
Result:=MetaData.Items[Self]
else
Result:=''; //or whatever
end;
class constructor TPanelHelper2.SetUp;
begin
MetaData:=TDictionary<TPanel, string>.Create;
end;
class destructor TPanelHelper2.TearDown;
begin
MetaData.Free;
end;
To use this, put 2 panels on a form, then:
Panel1.PutData('panel1string');
Panel2.PutData('panel2string');
ShowMessage('Panel 1 metadata: ' + Panel1.ReadData);
ShowMessage('Panel 2 metadata: ' + Panel2.ReadData);
A nice trick, but it makes me wonder if I can do this on my TWebModuleWebServices. I do not have enough insight into the internal workings of Delphi (VMT etc) to answer these questions:
Is this safe?
Is there a better approach (Class helpers have their disadvantages, see e.g. Class Helpers Go and NoGo in Understanding Delphi Class (and Record) Helpers)?
Edit:
There is an error in the above question:
Since AfterDispatch and BeforeDispatch have the same Sender: TObject; Request: TWebRequest; Response: TWebResponse; parameters as the OnAction handlers is incorrect.The Sender is a TWebModuleWebservices for the AfterDispath/BeforeDispatch and a TWebActionItem for the OnAction handlers. I'm leaving it in because it would require a big question rewrite and it is not essential to the answer(s).
These handlers all have some identical local variables
You could also simply turn these local variables into private fields of the web module.
It´s safe, but not necessarely the best option for the problem presented.
In your place I would go for inheritance. I would create a subclass from TWebModule and add all the general functionality all the other TWebModules have in this class. Then I would change the current ancestor of the other TWebModules to be this new one.
The nice thing of the approach is that you can adopt it slowly and carefuly. You can create the base TWebModule for your application, add some behavior to it and choose one single of the other TWebModules to experience the inheritance advantages. You can adapt, redesign and test for the single TWebModule you chose.
After that you can go for another and another until getting all done.
Related
I have an extension method which is used to read a particular claim from the current ClaimsPrincipal. But I also need to check this value against a list of items which I have in the appsettings.json.
I had this working by using a ConfigurationBuilder() to read the appsettings directly in much the same way as the startup does, although instead of using
.SetBasePath(Directory.GetCurrentDirectory())
as I do in the startup, I was using
.SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location))
Which although isn't pretty, works fine.
However, when the Unit tests are run none of the following get me to where the appsettings are
Directory.GetCurrentDirectory()
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
and I cannot see a way of getting the IHostingEnvironment or something similar into the extension method to read out the appsettings, or indeed to ditch the ConfigurationBuilder() and get at IOptions in the extension method, in such a way that the unit test and the running code will work correctly.
I assume there must be a way of doing this? Although I expect that I should simply not be trying at all and lift the check against the list of items into another class entirely...
Putting business logic that may ever require dependencies into static methods is not recommended. This makes it difficult to inject dependencies into them. Options are few:
Redesign the static method into a service so dependencies can be injected through the constructor. (Recommended)
public class Foo : IFoo
{
private readonly IOptions<FooOptions> optionsAccessor;
public Foo(IOptions<FooOptions> optionsAccessor)
{
this.optionsAccessor = optionsAccessor ??
throw new ArgumentNullException(nameof(optionsAccessor));
}
public void DoSomething()
{
var x = this.optionsAccessor;
// Same implementation as your static method
}
}
Inject the dependencies as parameters of the extension method.
public static void DoSomething(this object o, IOptions<FooOptions> optionsAccessor)
{
// Implementation
}
Redesign the static method to be a facade over an abstract factory like this example.
I'm mocking my repository correctly, but in cases like show() it either returns null so the view ends up crashing the test because of calling property on null object.
I'm guessing I'm supposed to mock the eloquent model returned but I find 2 issues:
What's the point of implementing repository pattern if I'm gonna end up mocking eloquent model anyway
How do you mock them correctly? The code below gives me an error.
$this->mockRepository->shouldReceive('find')
->once()
->with(1)
->andReturn(Mockery::mock('MyNamespace\MyModel)
// The view may call $book->title, so I'm guessing I have to mock
// that call and it's returned value, but this doesn't work as it says
// 'Undefined property: Mockery\CompositeExpectation::$title'
->shouldReceive('getAttribute')
->andReturn('')
);
Edit:
I'm trying to test the controller's actions as in:
$this->call('GET', 'books/1'); // will call Controller#show(1)
The thing is, at the end of the controller, it returns a view:
$book = Repo::find(1);
return view('books.show', compact('book'));
So, the the test case also runs view method and if no $book is mocked, it is null and crashes
So you're trying to unit test your controller to make sure that the right methods are called with the expected arguments. The controller-method fetches a model from the repo and passes it to the view. So we have to make sure that
the find()-method is called on the repo
the repo returns a model
the returned model is passed to the view
But first things first:
What's the point of implementing repository pattern if I'm gonna end up mocking eloquent model anyway?
It has many purposes besides (testable) consisten data access rules through different sources, (testable) centralized cache strategies, etc. In this case, you're not testing the repository and you actually don't even care what's returned, you're just interested that certain methods are called. So in combination with the concept of dependency injection you now have a powerful tool: You can just switch the actual instance of the repo with the mock.
So let's say your controller looks like this:
class BookController extends Controller {
protected $repo;
public function __construct(MyNamespace\BookRepository $repo)
{
$this->repo = $repo;
}
public function show()
{
$book = $this->repo->find(1);
return View::make('books.show', compact('book'));
}
}
So now, within your test you just mock the repo and bind it to the container:
public function testShowBook()
{
// no need to mock this, just make sure you pass something
// to the view that is (or acts like) a book
$book = new MyNamespace\Book;
$bookRepoMock = Mockery::mock('MyNamespace\BookRepository');
// make sure the repo is queried with 1
// and you want it to return the book instanciated above
$bookRepoMock->shouldReceive('find')
->once()
->with(1)
->andReturn($book);
// bind your mock to the container, so whenever an instance of
// MyNamespace\BookRepository is needed (like in your controller),
// the mock will be loaded.
$this->app->instance('MyNamespace\BookRepository', $bookRepoMock);
// now trigger the controller method
$response = $this->call('GET', 'books/1');
$this->assertEquals(200, $response->getStatusCode());
// check if the controller passed what was returned from the repo
// to the view
$this->assertViewHas('book', $book);
}
//EDIT in response to the comment:
Now, in the first line of your testShowBook() you instantiate a new Book, which I am assuming is a subclass of Eloquent\Model. Wouldn't that invalidate the whole deal of inversion of control[...]? since if you change ORM, you'd still have to change Book so that it wouldn't be class of Model
Well... yes and no. Yes, I've instantiated the model-class in the test directly, but model in this context doesn't necessarily mean instance of Eloquent\Model but more like the model in model-view-controller. Eloquent is only the ORM and has a class named Model that you inherit from, but the model-class as itself is just an entity of the business logic. It could extend Eloquent, it could extend Doctrine, or it could extend nothing at all.
In the end it's just a class that holds the data that you pull e.g. from a database, from an architecture point of view it is not aware of any ORM, it just contains data. A Book might have an author attribute, maybe even a getAuthor() method, but it doesn't really make sense for a book to have a save() or find() method. But it does if you're using Eloquent. And it's ok, because it's convenient, and in small project there's nothing wrong with accessing it directly. But it's the repository's (or the controller's) job to deal with a specific ORM, not the model's. The actual model is sort of the outcome of an ORM-interaction.
So yes, it might be a little confusing that the model seems so tightly bound to the ORM in Laravel, but, again, it's very convenient and perfectly fine for most projects. In fact, you won't even notice it unless you're using it directly in your application code (e.g. Book::where(...)->get();) and then decide to switch from Eloquent to something like Doctrine - this would obviously break your application. But if this is all encapsulated behind a repository, the rest of your application won't even notice when you switch between databases or even ORMs.
So, you're working with repositories, so only the eloquent-implementation of the repository should actually be aware that Book also extends Eloquent\Model and that it can call a save() method on it. The point is that it doesn't (=shouldn't) matter if Book extends Model or not, it should still be instantiable anywhere in your application, because within your business logic it's just a Book, i.e. a Plain Old PHP Object with some attributes and methods describing a book and not the strategies how to find or persist the object. That's what repositories are for.
But yes, the absolute clean way is to have a BookInterface and then bind it to a specific implementation. So it could all look like this:
Interfaces:
interface BookInterface
{
/**
* Get the ISBN.
*
* #return string
*/
public function getISBN();
}
interface BookRepositoryInterface()
{
/**
* Find a book by the given Id.
*
* #return null|BookInterface
*/
public function find($id);
}
Concrete implementations:
class Book extends Model implements BookInterface
{
public function getISBN()
{
return $this->isbn;
}
}
class EloquentBookRepository implements BookRepositoryInterface
{
protected $book;
public function __construct(Model $book)
{
$this->book = $book;
}
public function find($id)
{
return $this->book->find($id);
}
}
And then bind the interfaces to the desired implementations:
App::bind('BookInterface', function()
{
return new Book;
});
App::bind('BookRepositoryInterface', function()
{
return new EloquentBookRepository(new Book);
});
It doesn't matter if Book extends Model or anything else, as long as it implements the BookInterface, it is a Book. That's why I bravely instantiated a new Book in the test. Because it doesn't matter if you change the ORM, it only matters if you have several implementations of the BookInterface, but that's not very likely (sensible?), I guess. But just to play it safe, now that it's bound to the IoC-Container, you can instantiate it like this in the test:
$book = $this->app->make('BookInterface');
which will return an instance of whatever implementation of Book you're currently using.
So, for better testability
Code to interfaces rather than concrete classes
Use Laravel's IoC-Container to bind interfaces to concrete implementations (including mocks)
Use dependency injection
I hope that makes sense.
I'm trying to override the +initialize method of a class using ASOC, but I cannot find a way to override a class method. Is it even possible?
Not to let any confusion possible about the language I'm talking about, here's some code:
script FLAppDelegate
property parent: class "NSObject"
-- -- Class Methods -- --
-- Insert code here
end script
I've done some tests, and as far as I can tell, weird as it is, methods defined using AppleScriptObjC are both class and instance methods.
Let's say I have an AppleScriptObjC file:
script iTunesController
property parent: class "NSObject"
on playpause()
tell application id "com.apple.iTunes" to playpause
end playpause
end script
In an Objective-C method, both:
- (void)callASOC
{
iTunesControllerInstance = [NSClassFromString(#"iTunesController") new];
[iTunesControllerInstance playpause];
[iTunesControllerInstance release];
}
and
- (void)callASOC
{
[NSClassFromString(#"iTunesController") playpause];
}
will call the playpause handler in the AppleScriptObjC file. The latter formulation will generate a warning a compile time, but works.
I was not able to find any documentation confirming or refuting this.
Thanks to #Friziab who reminded me of the NSClassFromString
So I could call a AppleScriptObjC method in my AppDelegate.applescript from another class (script) (NSView subclass)
I don't use AppleScriptObjC so there may be a proper way of doing it but this worked
current application's NSClassFromString("AppDelegate")'s popWindow()
I'm looking for the best way to dynamically call a method from a different component in cfscript. Notice that it's concerning a method in a different component. So far I've tried 3 different methods, but none of them seem be exactly what I'm looking for:
All cases are written in cfscript inside a component method. Let's say I'm trying to dynamically call the setName(required string name) method in the MyComponent component. All cases have following variables defined:
var myComp = new MyComponent();
var myMethod = "setName";
var args = {"name"="foo"};
use evaluate() for the job
evaluate("myComp.#myMethod#(argumentCollection=args)");
pros: is done with very little code
cons: code is not very 'clean' and use of evaluate() seems to have an 'evil' reputation in the online community. I wouldn't want my code to be evil.
use a cfml wrapper for <cfinvoke>
invoke("MyComponent", myMethod, args);
pros: I can use all functionality of cfinvoke
cons: It creates a new instance of MyComponent with every invoke.
create a dynamicMethod method in MyComponent
myComp.dynamicMethod(myMethod, args);
dynamicMethod of MyComponent:
public any function dynamicMethod(required string methodName, required struct argumentColl){
var cfcMethod = variables[arguments.methodName];
return cfcMethod(argumentCollection=arguments.argumentColl);
}
pros: I can finally call myComp directly. Most comfortable solution so far.
cons: I can now call private methods of MyComponent via dynamicMethod.
(I've also tried the 'function as variable' solution outside of MyComponent, but then the function looses its working context. e.g. if MyComponent would extend a component, the 'super' scope would no longer refer to the extended component).
None of these solutions seem to be perfect, so is there no other way to call a dynamic function from a different controller?
And if there isn't, which one of these is the best solution?
Any advice is welcome, thanks.
Good analysis.
One thing you could do here is to more-closely emulate <cfinvoke> with your wrapper function. <cfinvoke> will take either a component path or a component instance (ie: an object) in that COMPONENT attribute. So your 'con' of 'It creates a new instance of MyComponent with every invoke.' isn't really valid.
ColdFusion 10, btw, adds a invoke() function to achieve just this. I note you're on CF9, so this is no help to you. But it's perhaps relevant for other people who might land on this question.
I've been reading Misko Hevery's classic articles about Dependency injection, and basically 'separating the object graph creation code from the code logic'.
The main idea seems to be "get rid of the 'new' operators", put them in dedicated objects ('Factories') and inject everything you depend on."
Now, I can't seem to wrap my head about how to make this works with objects that are composed of several other components, and whose job is to isolate those components to the outerworld.
Lame example
A View class to represent a combination of a few fields, and a button. All the components depend on a graphical ui context, but you want to hide it behind the interfaces of each sub-component.
So something like (in pseudo-code, language does not really matter I guess):
class CustomView() {
public CustomView(UIContext ui) {
this.ui = ui
}
public void start() {
this.field = new Field(this.ui);
this.button = new Button(this.ui, "ClickMe");
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
// The interface of this component is that callers
// subscribe to "addValueEnteredListener"..)
public void addValueEnteredListener(Callback ...) {
}
public void fireValueEnteredListener(text) {
// Would call each listeners in turn
}
}
The callers would do something like :
// Assuming a UIContext comes from somewhere...
ui = // Wherever you get UI Context from ?
v = new CustomView(ui);
v.addValueEnteredListener(function (text) {
// whatever...
});
Now, this code has three 'new' operators, and I'm not sure which one Misko (and other DI proponents) are advocating to rid off, or how.
Getting rid of new Field() and new Button()
Just Inject it
I don't think the idea here is to actually inject the instances of Field and Button , which could be done this way :
class CustomView() {
public CustomView(Field field, Button button) {
this.field = field;
this.button = button;
}
public void start() {
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
// ... etc ...
This makes the code of the component lighter, surely, and it actually hides the notion of UI, so the MetaForm component has clearly been improved in terms of readability and testability.
However, the burden is now on the client to create those things :
// Assuming a UIContext comes from somewhere...
ui = // wherever ui gets injected from
form = new Form(ui);
button = new Button(ui);
v = new CustomView(form, button);
v.addValueEnteredListener(function (text) {
// whatever...
});
That sounds really troubling to me, espacially since the client know has to all the inners of the class, which sounds silly.
Mama knows, inject her instead
What the articles seems to advocate is instead injecting a Factory to create the components elements.
class CustomView() {
public CustomView(Factory factory) {
this.factory = factory;
}
public void start() {
this.field = factory.createField();
this.button = factory.createButton();
this.button.addEventListener(function () {
if (field.getText().isEmtpy()) {
alert("Field should not be empty");
} else {
this.fireValueEntered(this.field.getText());
}
});
}
// ... etc ...
And then everything gets nice for the caller, because its just has to get the factory from somewhere (and this factory will be the only to know about the UI context, so hurray for decoupling.)
// Assuming a UIContext comes from somewhere...
factory = // wherever factory gets injected from
v = new CustomView(factory);
v.addValueEnteredListener(function (text) {
// whatever...
});
A possible drawback is that when testing the MetaForm, you will typically have to use a 'Mock' Factory that ... create Mocks version of the Field & Button classes. But obviously there is another drawback ...
Yo' Factory so fat!!
How big will the Factory get ? If you follow the pattern rigorously, then every single frigging component you ever want to create in you application at runtime (wich is typically the case for UI, right) will have to get its own createXXXXX methods in at least one factory.
Because now you need :
Factory.createField to create the field
Factory.createButton to create the button
Factory.createMetaForm to create the field, the button and the MetaForm when a client (say the MetaEditPage wants to use one)
And obviously a Factory.createMetaEditPage for the client..
... and its turtles all the way.
I can see some strategies to simplify this :
As much as possible, separate the parts of the graph that are created at "startup" time from the parts that are created at runtime (using an DI framework like Spring for the former, and factories for the latter)
Layer the factories, or collocate related objects in the same factories (a UIWidgetFactory would make sense for Field and Button, but where would you put the other ones ? In a Factory linked to the Application ? To some other logical level ?)
I can almost hear all the jokes from C guys that no Java app can do anything without calling a ApplicationProcessFactoryCreator.createFactory().createProcess().startApplication() chain of nonsense...
So my questions are :
I am completely missing a point here ?
If not, which strategy would you suggest to make the things bearable ?
Addendum : why I'm not sure dependency injection would help
Assume I decide to use dependency injection, with a guice-like framework. I would end up writing code like this :
class CustomView
#Inject
private Field fiedl;
#Inject
private Button button;
public void start() {
this.button.addEventListener(....
// etc...
And then what ?
How would my "Composition Root" make use of that ? I can certainely not configure a "singleton" (with a lowercase 's', as in 'the single instance of a class) for the Field and the Button (since I want to create as many instances of them as instances of MetaForm ?
It would not make sense to use a Provider, since my problem is not which instance of buttons I want to create, but just that I want to create it lately, with some configuration (for example its text) that only makes sense for this form.
To me DI is not going to help because I am new-ing parts of my component rather than Dependencies. And I suppose I could turn any subcomponent into a dependency, and let a framework inject them. It's just that injecting subcomponents looks really artificial and couter-intuitive to me, in this case... so again, I must be missing something ;)
Edit
In particular, my issue is that I can't seem to understand how you would test the following scenario :
"when I click on the button, if the Field is empty, there should be an error".
This is doable if I inject the button, so that I can call its "fireClicked" event manually - but it feels a bit silly.
The alternative is to just do view.getButton().fireClicked() , but that looks a bit ugly...
Well, you can use some DI Framework (Spring or Guice) and get rid of factory method completely. Just put some annotation on the field/constructor/set method and DI Framework will do the work. At unit-test use mock framework.
How about not being overly obsessed with the "no new" dogma ?
My take is that DI works well for - well you know, Dependencies, or Delegates. Your example is about composition and IMHO it absolutely makes sense that the owning entity (your CustomView) creates explicitly its components. After all, the clients of the composite do not even have to know that these components exist, how they are initialized or how you use them.