I'm building an application using the Supervising Controller pattern (Model View Presenter) and I am facing a difficulty. In my page I have a repeater control that will display each item of a collection I am passing to it. The reapeater item contains 2 dropdown list that allow the user to select a particular value. When I click the next button, I want the controller to retrieve those values.
How can I do that I a clean way?
You can also make a 'widget' interface for the drop down. I'll give you an easy example of a some working code for a TextBox widget so you get the idea.
public interface ITextWidget
{
event EventHandler TextChanged;
string Text { get; set; }
}
public abstract class TextWidget<T> : ITextWidget
{
protected T _wrappedWidget { get; set; }
public event EventHandler TextChanged;
protected void InvokeTextChanged(object sender, EventArgs e)
{
var textChanged = TextChanged;
if (textChanged != null) textChanged(this, e);
}
public abstract string Text { get; set; }
}
Notice that so far everything is technology agnostic. Now here's an implementation for a Win Forms TextBox:
public class TextBoxWidget : TextWidget<TextBox>
{
public TextBoxWidget(TextBox textBox)
{
textBox.TextChanged += InvokeTextChanged;
_wrappedWidget = textBox;
}
public override string Text
{
get { return _wrappedWidget.Text; }
set { _wrappedWidget.Text = value; }
}
}
This gets instantiated in the Form itself, which back to MVP is also the IViewWhatever:
public partial class ProjectPickerForm : Form, IProjectPickerView
{
private IProjectPickerPresenter _presenter;
public void InitializePresenter(IProjectPickerPresenter presenter) {
_presenter = presenter;
_presenter.InitializeWidgets(
...
new TextBoxWidget(txtDescription));
}
...
}
And in the Presenter:
public class ProjectPickerPresenter : IProjectPickerPresenter
{
...
public void InitializeWidgets(ITextWidget descriptionFilter) {
Check.RequireNotNull<ITextWidget>(descriptionFilter, "descriptionFilter");
DescriptionFilter = descriptionFilter;
DescriptionFilter.Text = string.Empty;
DescriptionFilter.TextChanged += OnDescriptionTextChanged;
}
...
public void OnDescriptionTextChanged(object sender, EventArgs e) {
FilterService.DescriptionFilterValue = DescriptionFilter.Text;
}
It's looks worse than it is to setup because most of the work is fairly mechanical once you get the idea. The clean part is that the presenter can get (and set) whatever info it needs on the widget without knowing or caring what the actual implemented widget is. It also lends itself to reuse with other widgets (you wind up building a library of them) of the same type (Win Forms here) and in other UI technologies as needed (once you have the interface / base class the implementation in another technology is trivial). It also is easy to test with mock objects because you have the interface. And your UI is now wonderfully ignorant of just about everything but UI related tasks. The downside is the bunch of classes per widget and a little learning curve to get comfortable with it.
For your drop down, your might just need the SelectedIndexChanged type event, which you'd substitute for this examples TextChanged event.
When controller-view interation get's too complex I usually split them up into subcontrollers and subviews.
You can have the items in the repeater be user-controls that have their own views and controllers. Your main view can then have a list of subviews(usercontrols) that have their own controllers that are maintained by the main controller.
When the user clicks next your main controller can signal all the subcontrollers to refresh their items from their views.
Related
I am working on a QtQuick 2 application (Qt version 6.2.3). I created one C++ class (let's call this class "Example") that contains the data that my application should deal with. This class can be instantiated several times, representing different datasets to be displayed.
class ExampleObject : public QObject {
Q_OBJECT
Q_PROPERTY(QString property1 MEMBER property1 CONSTANT)
...
public:
QString property1;
};
Q_DECLARE_METATYPE(ExampleObject*)
I want to be able to display instances of this class via QML, therefore I created a "Example" custom component with a property pointing to the Example C++ object containing the data I want to display.
ExampleComponent {
property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject
Label {
text: exampleCppObject.property1
}
}
To be able to change the Example instance used by the QML component, I created functions to "reinitialize" and "update" the component:
ExampleComponent {
property var exampleCppObject // exampleCppObject is a pointer to an instance of ExampleObject
property string textToDisplay
function update() {
textToDisplay=Qt.binding(() => exampleCppObject.property1);
}
function reinitialize() {
textToDisplay=""
}
Label {
text: textToDisplay
}
}
I call these functions after changing or deleting the Example object pointed by ExampleCppObject, and this works quite fine. But I feel like this isn't best practice, and it seems to me that I am doing things wrong.
What are better ways of connecting C++ to QML, in the situation I described?
Edit: my main.cpp essentially consists in:
MainModel mainModel;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("mainModel", &mainModel);
engine.load(QStringLiteral("qrc:/main.qml"));
Where mainModel is an object which can create different instances of ExampleObject while the application is running.
You can optimize the binding textToDisplay such that you don't have to call the upate and reinitialize functions, which seems to be the question you are after:
property var exampleCppObject
property string textToDisplay : exampleCppObject ? exampleCppObject.property1 : ""
In case you need more complex logic in the future, you can also use braces:
property string textToDisplay: {
console.log("log me everytime the binding is reevalutated")
if(condition1)
return "invalid"
else if(condition2)
return exampleCppObject.property2
else
return exampleCppObject.property1
}
The best part of this, is that QQmlEngine actually reevaluates the binding for every property that is used in this binding (which has a notify signal), so if crafted correctly, you can largely leave the binding alone (meaning you don't need the update and reinitialize function)
I'm learning CQRS recently, so I started a sample project with axon-framework(A java CRQS framework).
According to the quick start, I got this below:
public class CreditEntryUnitTests {
private FixtureConfiguration fixture;
#Before
public void setUp() throws Exception {
fixture = Fixtures.newGivenWhenThenFixture(CreditEntry.class);
}
#Test
public void creditEntryCreated() throws Throwable {
final Long entryId = 1L;
final int amount = 100;
fixture.given().when(new CreateCreditEntryCommand(entryId, amount))
.expectEvents(new CreditEntryCreatedEvent(entryId, amount));
}
#Test
public void creditEntryMadeEffective() throws Throwable {
final Long entryId = 1L;
final int amount = 100;
final Date start = nov(2011, 12);
final Date end = nov(2012, 12);// a year effective period
fixture.given(new CreditEntryCreatedEvent(entryId, amount))
.when(new MakeCreditEntryEffectiveCommand(entryId, start, end))
.expectEvents(new CreditEntryMadeEffectiveEvent(entryId, start, end));
}
//omitted support methods
}
public class CreditEntry extends AbstractAnnotatedAggregateRoot {
#AggregateIdentifier
private Long id;
private int amount;
private Date effectiveDateRangeStart;
private Date effectiveDateRangeEnd;
private Status status;
#CommandHandler
public CreditEntry(CreateCreditEntryCommand command) {
apply(new CreditEntryCreatedEvent(
command.getEntryId(), command.getAmount()));
}
#EventHandler
public void on(CreditEntryCreatedEvent event) {
this.id = event.getEntryId();
this.amount = event.getAmount();
this.status = Status.NEW;
}
#CommandHandler
public void markCompleted(MakeCreditEntryEffectiveCommand command) {
apply(new CreditEntryMadeEffectiveEvent(
command.getEntryId(), command.getStart(), command.getEnd()));
}
#EventHandler
public void on(CreditEntryMadeEffectiveEvent event) {
this.effectiveDateRangeStart = event.getStart();
this.effectiveDateRangeEnd = event.getEnd();
this.status = Status.EFFECTIVE;
}
public CreditEntry() {}
public enum Status {
NEW, EFFECTIVE, EXPIRED
}
}
The test code drives me written the domain model and integration code with axon-framework but it doesn't cover what side effect the event made. Where did I test them? e.g. when made effective the credit entry's status should be effective. Should I create a CreditEntry instance in other test methods and test by calling specific on(...Event event) method?
And one more question is: where should I put business validation logic? In command handler method? Assuming if the CreditEntry can not be made effective again given it is effective already.
#CommandHandler
public void markCompleted(MakeCreditEntryEffectiveCommand command) {
if (is(NEW)) {
apply(new CreditEntryMadeEffectiveEvent(
command.getEntryId(), command.getStart(), command.getEnd()));
} else {
throw new IllegalStateException(.......);
}
}
Any idea is appreciate, thank you.
On your first question:
Do you mean by side effect the internal state of your aggregate object? The Given-When-Then fixture test treat the aggregate as a kind of black box. So indeed, there is no real need to test the internal state. It is only important that the right events are applied.
So for example, you might even end up with aggregates without any fields (expect the ID) as your decision logic does not depend on any internal state. As a rule of thumb, I only save data transported in an event in the aggregate object if I need it later to decide which events to apply or if it changes the data applied in an event.
If you keep that in mind, you don't really have to test the internal state. You simply configure an aggregate with specific events in the given clause (build up some state) and then apply a command. If the correct events come out... you're done.
On your second question:
Business validation should go in the command handler. So everything should be validated before the applymethod is called. One reason for this: Imagine a system in which the validation logic changes over the life time, but you have to deal with old data which was entered when the system was introduced. If the validation would be in the event handler and the validation is not the same as when the event was first introduced, loading your aggregate from the events might fail as the "old" data does not match to the current validation logic.
I have a toolbar controller which is capable of updating the toolbar state ( enabled/disabled, pressed/unpressed ) by querying document properties or the application framework. I have some buttons that represent the current state of a view.
From an application design standpoint I like having toolbar controller able to update the button state at any time given a document. I also prefer the toolbar controller & button handlers to have no internal state.
Options as I see it - looking for other suggestions:
Create a mechanism for visiting all views of a document with a visitor that can capture the state of the view which is then used to enable/disable/press/depress the button.
Create some connection between views and toolbar handlers that allows the toolbar buttons to directly ask the views.
Other??
you can try having an event loop for the view and update the state with a function call dispatch
Like this:
class ViewEventArgs{
public:
int eventNumber;
};
class ViewEvent{
public:
virtual void onViewChange(ViewEventChangeArgs args) = 0;
};
class ViewController{
public:
virtual void doPressed() = 0;
virtual void doChecked() = 0;
//other interface methods
};
class ToolbarView : public ViewEvent{
public:
//Your EVENT-LOOP kernel will fire these events depending upon the state change in the view
void onViewChange(ViewEventChangeArgs args)
{
switch(args.eventNumber){
case PRESSED:
getToolbarController()->doPressed();//the method dispatch
break;
case CHECKED:
getToolbarController()->doChecked();
}
}
//other parts of the view
};
class ToolbarController: public ViewController{
public:
void doPressed() { /*pressed*/ }
void doChecked() { /*checked*/ }
//implementations
};
I want to write some unit tests for an interceptor that intercepts the Loggable base class (which implements ILoggable).
The Loggable base class has no methods to call and it is used only to be initialized by the logging facility.
To my understanding I should:
Mock an ILoggable and an ILogger
Initialize the logging facility
Register my interceptor on it
Invoke some method of the mocked ILoggable
The problem is that my ILoggable interface has no methods to call and thus nothing will be intercepted.
What is the right way to act here?
Should I mock ILoggable manually and add a stub method to call?
Also, should I be mocking the container as well?
I am using Moq and NUnit.
EDIT:
Here's my interceptor implementation for reference:
public class LoggingWithDebugInterceptor : IInterceptor
{
#region IInterceptor Members
public void Intercept(IInvocation invocation)
{
var invocationLogMessage = new InvocationLogMessage(invocation);
ILoggable loggable = invocation.InvocationTarget as ILoggable;
if (loggable == null)
throw new InterceptionFailureException(invocation, string.Format("Class {0} does not implement ILoggable.", invocationLogMessage.InvocationSource));
loggable.Logger.DebugFormat("Method {0} called with arguments {1}", invocationLogMessage.InvokedMethod, invocationLogMessage.Arguments);
Stopwatch stopwatch = new Stopwatch();
try
{
stopwatch.Start();
invocation.Proceed();
stopwatch.Stop();
}
catch (Exception e)
{
loggable.Logger.ErrorFormat(e, "An exception occured in {0} while calling method {1} with arguments {2}", invocationLogMessage.InvocationSource, invocationLogMessage.InvokedMethod, invocationLogMessage.Arguments);
throw;
}
finally
{
loggable.Logger.DebugFormat("Method {0} returned with value {1} and took exactly {2} to run.", invocationLogMessage.InvokedMethod, invocation.ReturnValue, stopwatch.Elapsed);
}
}
#endregion IInterceptor Members
}
If it's just the interceptor that uses the Logger Property on your class than why have in there at all? You might just as well have it on the interceptor. (like Ayende explained in his post here).
Other than that - interceptor is just a class which interacts with an interface - everything highly testable.
I agree with Krzysztof, if you're looking to add Logging through AOP, the responsibility and implementation details about logging should be transparent to the caller. Thus it's something that the Interceptor can own. I'll try to outline how I would test this.
If I follow the question correctly, your ILoggable is really just a naming container to annotate the class so that the interceptor can determine if it should perform logging. It exposes a property that contains the Logger. (The downside to this is that the class still needs to configure the Logger.)
public interface ILoggable
{
ILogger { get; set; }
}
Testing the interceptor should be a straight-forward process. The only challenge I see that you've presented is how to manually construct the IInvocation input parameter so that it resembles runtime data. Rather than trying to reproduce this through mocks, etc, I would suggest you test it using classic State-based verification: create a proxy that uses your interceptor and verify that your log reflects what you expect.
This might seem like a bit more work, but it provides a really good example of how the interceptor works independently from other parts of your code-base. Other developers on your team benefit from this as they can reference this example as a learning tool.
public class TypeThatSupportsLogging : ILoggable
{
public ILogger { get; set; }
public virtual void MethodToIntercept()
{
}
public void MethodWithoutLogging()
{
}
}
public class TestLogger : ILogger
{
private StringBuilder _output;
public TestLogger()
{
_output = new StringBuilder();
}
public void DebugFormat(string message, params object[] args)
{
_output.AppendFormat(message, args);
}
public string Output
{
get { return _output.ToString(); }
}
}
[TestFixture]
public class LoggingWithDebugInterceptorTests
{
protected TypeThatSupportsLogging Input;
protected LoggingWithDebugInterceptor Subject;
protected ILogger Log;
[Setup]
public void Setup()
{
// create your interceptor
Subject = new LoggingWithDebugInterceptor();
// create your proxy
var generator = new Castle.DynamicProxy.ProxyGenerator();
Input = generator.CreateClassProxy<TypeThatSupportLogging>( Subject );
// setup the logger
Log = new TestLogger();
Input.Logger = Log;
}
[Test]
public void DemonstrateThatTheInterceptorLogsInformationAboutVirtualMethods()
{
// act
Input.MethodToIntercept();
// assert
StringAssert.Contains("MethodToIntercept", Log.Output);
}
[Test]
public void DemonstrateNonVirtualMethodsAreNotLogged()
{
// act
Input.MethodWithoutLogging();
// assert
Assert.AreEqual(String.Empty, Log.Output);
}
}
No methods? What are you testing?
Personally, this sounds like it goes too far. I realize that TDD and code coverage is dogma, but if you mock an interface with no methods and prove that the mocking framework does what you instructed it to do, what have you really proven?
There's another misdirection going on here: logging is the "hello world" of aspect oriented programming. Why aren't you doing logging in an interceptor/aspect? If you did it that way, there'd be no reason for all your classes to implement ILoggable; you could decorate them with logging capability declaratively. I think it's a less invasive design and a better use of interceptors.
I have a user control that has button whose click event handler contains the core logic. I want to test this button click handler.
This handler function calls a public function of another user control (which resides in separate C# project) which ultimately calls public function of a reference assembly.
Can anyone please tell me - how will be the unit test for such a handler?
In unit testing, we test the Unit - in this case, the user control. And nothing more. But we shouldn't allow the user control to access outside world, we should use mocking techniques.
In example, if your UserControlA calls UserControlB, create an interface for UserControlB and replace it with a mock UserControlB :
class UserControlA {
UserControlBInterface BReference;
public void setBReference(UserControlBInterface reference) { this.BReference = reference };
void OnClick (...) { BReference.callAMethod(); }
}
class MockupForB : UserControlBInterface {
boolean called=false;
public void callAMethod() { this.called = true; }
}
class TesterA : UnitTest {
public void testOnClick()
{ UserControlA a = new UserControlA(); MockupForB mockup = new MockupForB(); a.setBReference(mockup);
a.Button1.PerformClick(...); //following Aaronontheweb's advice
assertTrue(mockup.called,"the method callAMethod not being called by UserControlA");
}
}
And to ensure UserControlB indeed calls a reference library, this belongs to unit test for UserControlB.
You can write a method that programmatically raises the Click event and call that from your unit test.
Edit: Ah, this actually exists already: http://msdn.microsoft.com/en-us/library/hkkb40tf(VS.90).aspx