Guidance to migration of legacy app and unit testing

We are in the process of migrating an old 2.0 app to mvc5 webapi 2 and Aurelia. Currently the designer and developer are not breaking the pages down into components perhaps as much as they should and some of the old pages are very complex with a lot of logic. I have a sample of a simple page that we converted here C&C please.

I could use some guidance about unit testing on the Aurelia side. We do not have a lot of experience with unit testing but have some concerns.

  1. Some of the examples I see of unit testing show using Aurelia-bootstrap and component testing. What is the value of this? Shouldn’t the binding already be working and tested it seems like you are not testing the js methods in isolation but it is an integration test of Aurelia, the DOM, and javascript methods.

  2. I feel that refactoring and testing the methods would be of more isolated. If the dom, client.fetch, and Aurelia bindings is not part of the methods under test.

  3. Has anyone seen or know of a real world project with unit-tests that I could look at the structure of the project and unit testing on github or other public repository?

Anyone using unit tests and Aurelia please leave some feedback as how to handle this large project at the 50,000 foot level.

1 Like

You shouldnt need the testbed approach, means staging components under test, for the most times. This technique is ideal If you want to test DOM related concerns, specifically when testing a 3rd party script used by the component. MVVM separates the View from the ViewModel so testing later with pure isolated unit tests should suffice for the most part. With regards to structure, both the skeletons and cli place the tests into a Test folder not next to your components. That works quite well but can be changed If you prefer having the tests next to the code.
I would split the tests in multiple files, nevertheless where they are.
Most apps with large coverage are private so maybe take a look at Aurelia plugins instead. E.g checkout aurelia-store as an example including Code coverage.

1 Like

Furthermore looking at your examples I see a few issues:

  • Try to follow the AAA principle of testing code and prefer 5 Tests with 1 Assertion over 1 Test with 5 Assertions. That doesn’t mean you’re not allowed to add multiple assertions but should only focus on asserting one specific behavior. In your first test you assert on multiple things, where already the test name indicates a too broad spec. I’d as mentioned split this up in few smaller tests. Don’t care about execution time, tests are running really fast but the readability will be important once the code base grows.
  • Try to avoid beforeEach/afterEach setups and teardowns, as they promote the use of global variables, which could lead to flaky tests, instead each function should simply call an arrange function. Sample
  • Don’t change the behavior with Mocks. In your sample the beforeEach block mocks the abafetch method and makes it sync vs as originally using a promise from fetch. This will lead to unpredictable sideeffects sooner or later. Instead mock out this.client.fetch and make it return a faked promise response, so that the rest of the code stays as it is. That way you can easily test once with a errorResponse and check the catch part and once with a successResponse for the then part.

We do have a folder structure that matches src under test. I only put all three files together for the simplicity of posting it under pastebin.

So. If I am reading your comments right So far I have the following take aways.

  1. try to only have one assert per test.
  2. try not to use beforeEach/afterEach
  3. Testing the dom interaction would be if we were using some 3rd party component that might change, and we would want to see if it suddenly breaks.

Thanks for the feedback so far.

Yep, don’t forget proper mocks as well :wink: