Skip to content

Add mock protocols and view mocks#19

Open
Grubas7 wants to merge 4 commits intomasterfrom
add_mocking
Open

Add mock protocols and view mocks#19
Grubas7 wants to merge 4 commits intomasterfrom
add_mocking

Conversation

@Grubas7
Copy link
Copy Markdown
Owner

@Grubas7 Grubas7 commented Mar 13, 2018

WHAT:

  • add mock protocols
  • add view mocks

WHY:

  • DeviceViewMockable gives us possibility to create objects for specific test case, e.g.
struct Phone_4Inches: DeviceViewMockable {
    var name = "iPhone SE"
    var size = .init(width: 320.0, height: 568.0)
    var layoutMargins = .init(top: 8.0, left: 16.0, bottom: 8.0, right: 16.0)
    ...
}
  • MockingView gives easy to use View mock container

TO CONSIDER 🤔

  • maybe MockingView should be called StubingView? Same for protocols.

@Grubas7 Grubas7 added this to the 0.1.0 milestone Mar 13, 2018
@Grubas7 Grubas7 self-assigned this Mar 13, 2018

/// A set of properties that provide information about device.
@objc(AGDeviceMockable)
public protocol DeviceMockable {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeviceMockable > MockableDevice?

import Foundation
import UIKit

public typealias DeviceViewMockable = ViewMockable & DeviceMockable
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeviceViewMockable > MockableDeviceView?

@@ -0,0 +1,102 @@
//
// MockingDeviceView.swift
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MockingDeviceView or MockedDeviceView? 🧐

Copy link
Copy Markdown
Owner Author

@Grubas7 Grubas7 May 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably you are right.
Mocking and Mockable is good for protocol (https://swift.org/documentation/api-design-guidelines/#protocols-describing-what-is-should-read-as-nouns) and for class probably MockedDeviceView would be better.

Please check also remark: #19 (comment)

Copy link
Copy Markdown
Collaborator

@aleksandergrzyb aleksandergrzyb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of questions. 👌 Looks really nice.

var name: String { get set }

/// Interface orientation to stub.
var orientation: UIInterfaceOrientation { get set }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why UIInterfaceOrientation and not UIUserInterfaceSizeClass? I don't know if combination of UIUserInterfaceIdiom and UIInterfaceOrientation makes sense. UIUserInterfaceIdiom can be UIUserInterfaceIdiomCarPlay, what orientation has this class then?

If we want to support only iOS (iPhone and iPad) we should be more specific than UIUserInterfaceIdiom, maybe create own type.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why UIInterfaceOrientation and not UIUserInterfaceSizeClass? I don't know if combination of UIUserInterfaceIdiom and UIInterfaceOrientation makes sense.

UIUserInterfaceSizeClasses are defined in ViewMockable protocol.

UIUserInterfaceIdiom can be UIUserInterfaceIdiomCarPlay, what orientation has this class then?

I have never checked interface orientation on CarPlay, but UIInterfaceOrientation has value .unknown so in worst case we could use that.

If we want to support only iOS (iPhone and iPad) we should be more specific than UIUserInterfaceIdiom, maybe create own type.

I don't think we have to limit only to iOS. Car play and tvOS probably can be supported out of box, watchKit requires some work.


public typealias DeviceViewMockable = ViewMockable & DeviceMockable

/// View stubing layout defining properties and information about device.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stubingstubbing (same for other files)

/// Additionally `mockParameters` contains information about mocked device,
/// which can be use to distinguish interface orientation or device model.
@objc(AGMockingDeviceView)
public class MockingDeviceView: UIView {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe DeviceMockView? I find those classes names and protocols pretty confusing.

Copy link
Copy Markdown
Owner Author

@Grubas7 Grubas7 May 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if Mock/Mocking/Mockable word is correctly used.

mock objects are simulated objects that mimic the behavior of real objects in controlled ways*

And this is a UIView subclass, so it's not a abstract object that try to fulfil our expectation, but it's normal class. The behaviour that I'm trying to achieve is basically inject some read-only data to UIView instance. Maybe more precise name would be StubbedView/StubbedDeviceView?

*https://en.wikipedia.org/wiki/Mock_object

/// Some of layout properties (e.g. `safeAreaInsets`, or `traitCollection`) are read-only,
/// so this view can be used as container which helps to force custom layout.
@objc(AGMockingView)
public class MockingView: UIView {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When one could use MockingView instead of DeviceMockingView? Did you consider making one a subclass of another? It looks like lots of code duplication.

Copy link
Copy Markdown
Owner Author

@Grubas7 Grubas7 May 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When one could use MockingView instead of DeviceMockingView?
MockingView might be useful for simple testing cases, eg: Developer needs to test some view for larger content size category or custom trait collection.

DeviceMockingView should be used for testing view on specific device eg. iPad (so mockParameters would contains whole set of iPad UI specific values like: size and safe area insets) and additionally values which are useful for describing reference images (eg. orientation [on iPad height > width not always means portrait orientation], device name)

Did you consider making one a subclass of another? It looks like lots of code duplication.

Subclass is impossible because of mockParameters property has different type in MockingView and DeviceMockingView. I reduced trait collection logic.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subclass is impossible because of mockParameters property has different type in MockingView and DeviceMockingView.

What about making just one subclass of UIView that has two initializers (ViewMockable and DeviceViewMockable)? This kind of generic class would just be one purpose class that would be passed to FBSnapshotVerify(...) method. I think it would make usage a little simpler while preserving all the functionality. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants