2

I recently started designing my first MVP-app. I like the idea of having a "dumb" view to be able to cover as much of the code with unit tests.

The app I build will be an app to create offers (besides other functionality). So the UI shold have a list of positions (with prices) and these positions can be part of a category (a category shows the price of all it's positions). The positions should be able to change their location inside their category, so I need an ID which holds the place of the positions and categories.

My question:

Is this the idea of a "dumb view" or does it make sense to make it even more "dumb"? I could also pass the value of the dropdown box to the presenter and then save it there instead of handling this in the view.

Code and Example

An example of the list:

/button and dropdown menu to add position or category (there may be positions outside a category)

Cat. Materials (total price 200.-) /button to add position

  • position A 100.- /button to add other position
  • position B 100.- /button to add other position

Cat. Work done (total price 400.-) /same buttons as in cat. before

  • position C 100.-
  • position C 300.-

total price: 600.-

Here is the P and V code to add a position or category (it's in JS. The code does not work, it's just to get an idea of how this could be implemented):

View:

init(presenter){
    this._presenter = presenter;
   //all add-buttons call the same method
    addButton.addEventListener("click", this._onClickAddCatOrPosition.bind(this));
}

_onClickAddCatOrPosition(){
    switch(dropdownMenu.type){
        case "position":
            this._presenter.addPosition(idOfPrevItem, parentId, name, this.addPositionAt.bind(this));
            break;
        case "category":
            this._presenter.addCategory(idOfPrevItem, parentId,name, this.addCategoryAt.bind(this));
            break;
    }
}

addPositionAt(name, id, idOfPrevItem, parentId){
    //add new position after idOfPrevItem and save it's parentId and id
}

addCategoryAt(name, id, idOfPrevItem, parentId){}

Presenter:

addPosition(idOfPrevItem, parentId, name, onAdded){
    let newId = this._modelMain.addPositionAt(idOfPrevItem, parentId, name);

    onAdded(name, newId, idOfPrevItem, parentId);
}

addCategory(idOfPrevItem, parentId, name, onAdded){
    let newId = this._modelMain.addCategoryAt(idOfPrevItem, parentId, name);

    onAdded(name, newId, idOfPrevItem, parentId);
}
1
  • I took the liberty to edit your question to remove the request for an opinion. Discussion-style questions are not supported by this community, however I think the rest of the question is on-topic. If this is truly not what you want, feel free to revert my edit. Commented Apr 22 at 19:08

1 Answer 1

6

I like the idea of having a "dumb" view to be able to cover as much of the code with unit tests.

I like the idea as well. It follows a pattern Martin Fowler called the Humble Object which advises moving all logic out of any hard to test object into a testable object.

I take testable to mean the objects behavior is deterministic, free of IO, and doesn't require goofy magic to configure, call and test. You know, functional.

One thing that is not those things is a GUI. Now sure, you said View not GUI. But GUI code has to live somewhere. Under the MVP pattern people often dump the GUI in the View. That's fine. But where ever you put the hard to test GUI code should not be where you put any interesting, test needing, logic. Put that behind an API that the GUI and tests can call without the logic knowing which called it.

Do that and you wont have to install any weird frameworks to click buttons for you.


does it make sense to make it even more "dumb"?

When I see this code:

_onClickAddCatOrPosition(){
    switch(dropdownMenu.type){

I ask myself, "how is a test going to set and pass dropdownMenu.type?"

If the answer to that isn't simple, consider getting humble.

Couldn't this switch live in something that makes passing that simple? switch screams interesting behavior...

2
  • Thanks for your answer! I see your point with the switch statement. In JS in my experience it's not too complicated to mock the DOM (with jest-dom). But I agree, I would prefer not to use this and I like the idea to not test the view. I just watched this video from Erik Kuefler: youtube.com/watch?v=kilmaSRq49g. He says what I was also reflecting: If I take every logic out of the view, I will always have to change the view and the presenter even if I change something very small. In my case: if I replace the dropdown box with two separate buttons. Any thoughts on that?
    – Ennio
    Commented Apr 24 at 13:50
  • @Ennio I'm watching that video now. Here Erik defines MVP and gives a textbook argument for keeping the view humble and moving it's logic to the presenter. I only mention the GUI to make clear what I'm saying is hard to test. If your view is nothing but GUI (and free of test needing logic) then we're saying the same thing. Commented Apr 25 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.