Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add address form tests #114

Merged
merged 12 commits into from
Feb 28, 2018
Merged

Add address form tests #114

merged 12 commits into from
Feb 28, 2018

Conversation

AntonoffEvgeniy
Copy link
Contributor

Add address form tests

@AntonoffEvgeniy AntonoffEvgeniy force-pushed the feature/address_form_tests branch 2 times, most recently from 75dd7d0 to 468fb5a Compare February 26, 2018 15:03
@AntonoffEvgeniy AntonoffEvgeniy requested review from plzen and radyslavkrechet and removed request for plzen and radyslavkrechet February 26, 2018 15:34
@radyslavkrechet
Copy link
Contributor

Where is a test spec for AddressFormViewController?


describe("when view model initialized") {
it("should have variables with correct initial values") {
expect(viewModel.address).to(beNil())
Copy link
Contributor

Choose a reason for hiding this comment

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

You also need to check all rx variables that initialized with empty string.

it("should return correct contry names") {
viewModel.namesOfCountries
.subscribe(onNext: { names in
expect(names) == ["Country1", "Country2"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Use toEventually method to compare values in subscribe closures if this subject changes after subscription.

}

context("if states not found") {
it("should return empty array") {
Copy link
Contributor

Choose a reason for hiding this comment

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

You also need to check stateText.value = "" in this test case.


viewModel.filledAddress
.subscribe(onNext: { filledAddress in
expect(filledAddress.country) == address.country
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to cover all changes so test all variables that can be changed by updateFields method call.

@testable import ShopApp

class AddressFormViewModelSpec: QuickSpec {
override func spec() {
Copy link
Contributor

Choose a reason for hiding this comment

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

You also need to test isAddressValid and submitTapped properties.


describe("when view loaded") {
beforeEach {
viewController = UIStoryboard(name: StoryboardNames.account, bundle: nil).instantiateViewController(withIdentifier: ControllerIdentifiers.addressForm) as! AddressFormViewController
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are you duplicate initialization of controller and outlets few times? We can do it one time in beforeEach closure before first describe closure with test cases.

viewModelMock = AddressFormViewModelMock(countriesUseCase: addressFormUseCaseMock)
viewController.viewModel = viewModelMock

countryPicker = self.findView(withAccessibilityLabel: "addressFormCountryPicker", in: viewController.view) as! BasePicker
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid this init in each test case? We already do it in previous beforeEach method

viewModelMock.makeSubmitButtonEnabled()

viewController.viewModel.filledAddress
.subscribe(onNext: { address in
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid subscription in test case and test real binding between view controller and view model?


it("should return correct contry names") {
viewModel.namesOfCountries
.subscribe(onNext: { names in
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid all subscriptions in tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's PublishSubject, so we need to subscription in this case


context("if it doesn't have any symbols in each text field view") {
it("needs to disable submit button") {
expect(submitButton.isEnabled) == false
Copy link
Contributor

Choose a reason for hiding this comment

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

Add viewModelMock.makeSubmitButtonDosabled() before expect, it will be more correct, especially in case when this test case will be execute after previous one.

})
.disposed(by: disposeBag)

viewModelMock.submitTapped.onNext()
Copy link
Contributor

Choose a reason for hiding this comment

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

It should be submit button action, not view model observer event. With whit changes you automatically test binding between button and view model.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also test that view end editing after button pressed.

@testable import ShopApp

class AddressFormViewControllerSpec: QuickSpec {
override func spec() {
Copy link
Contributor

Choose a reason for hiding this comment

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

You also need to test:

  • binding of text fields/pickers with view model's variables
  • pickers' item select actions (if it possible)
  • pickers' custom data and text that setup with data from view model's subscription

}

it("should select country correctly") {
countryPicker.pickerView.selectRow(0, inComponent: 0, animated: false)
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't you need to call viewModelMock.makeNameOfCountries() before testing?

})
.disposed(by: disposeBag)

viewModelMock.makeNameOfCountries()
Copy link
Contributor

Choose a reason for hiding this comment

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

Make arguments for this method and pass values which need to be emitted from test. It will be more readable.

})
.disposed(by: disposeBag)

viewModelMock.makeNameOfStates()
Copy link
Contributor

Choose a reason for hiding this comment

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

Make arguments for this method and pass values which need to be emitted from test. It will be more readable.

}
}

func initData(addressNeeded: Bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This func should be private

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, but we have error 'Attribute 'private' can only be used in a non-local scope'. If we want to move this method out of 'spec()' function, it also need to move all properties (like viewController, viewModel, etc)

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, lets use your way


viewModel.namesOfStates
.subscribe(onNext: { names in
expect(names.isEmpty) == false
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we check here if nameOfStates returns what we expected?


context("if address not filled") {
beforeEach {
address = Address()
Copy link
Contributor

Choose a reason for hiding this comment

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

You can name this field like validAddress or invalidAddress for more readable - not issue, but can improve tests in future

}

it("should have correct view model namesOfCountries binding") {
viewController.viewModel.namesOfCountries
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you really need subscription here?

}

it("should have correct view model namesOfStates binding") {
viewController.viewModel.namesOfStates
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you really need subscription here?

@AntonoffEvgeniy AntonoffEvgeniy merged commit cfc8775 into develop Feb 28, 2018
@AntonoffEvgeniy AntonoffEvgeniy deleted the feature/address_form_tests branch February 28, 2018 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants