unit testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •test individual components...
TRANSCRIPT
![Page 1: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/1.jpg)
Unit Testing in .NET
![Page 2: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/2.jpg)
Philosophy of Unit Testing
• What?
• Where?
• Why?
• How?
• What it is not?
![Page 3: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/3.jpg)
• Test individual components (units)
• in isolation
• to confirm preexisting specification.
• Inputs … -> expected results
• Test functions, methods.
• Use a framework to make it easier (xUnit or ?Unit)
isolate and validate
verify
![Page 4: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/4.jpg)
• Write tests after creating specification, but before implementing methods.
• Best if written by the developer or the development team. Why?
• Test-driven development
• Supports regression testing
![Page 5: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/5.jpg)
The Art of Unit Testing, by R Osherov
![Page 6: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/6.jpg)
![Page 7: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/7.jpg)
![Page 8: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/8.jpg)
![Page 9: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/9.jpg)
1 Unit Test
assertions
![Page 10: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/10.jpg)
Test Suite
Test Case
Test Case
Test Case
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Unit testUnit testUnit test
Run with TestRunner
![Page 11: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/11.jpg)
Assertions
http://junit.sourceforge.net/javadoc/org/junit/Assert.html
JUnit
assertEquals() assertFalse() assertNotNull() assertNotSame() assertNull() assertSame() …
By the way, you should use assertions in everyday programming
Java: assert i > 0; C#: Debug.Assert( i > 0 ); Python: assert i > 0
![Page 12: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/12.jpg)
NUnit Assertions
Classic ModelAssert.isEmpty() Assert.areEqual() Assert.Null() Assert.notNull() …
https://github.com/nunit/docs/wiki/Classic-Model
Constraint Model
Assert.That()
https://github.com/nunit/docs/wiki/Constraint-Model
![Page 13: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/13.jpg)
NUnit
Assert.That( aString, Is.Empty ); Assert.That( aString, Is.Not.Empty ); Assert.That( 2 + 2, Is.EqualTo(4.0) ); Assert.That( 5.5, Is.EqualTo( 5 ).Within(1.5).Percent ); Assert.That( "Hello!", Is.Not.EqualTo( "HELLO!" ) ); Assert.That( "Hello!", Is.EqualTo( "HELLO!" ).IgnoreCase );
constraint
![Page 14: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/14.jpg)
Good Habits• Try to make tests independent or orthogonal to other tests
• Test only one code unit at a time
• Don’t name your tests: test0, test1, …
• Use setup and teardown to create a clean environment for each test
• Don’t have unit tests access your database — use fake data (write a “mock” object that meets the same interface) ==> break dependencies
• Refactor to make your code more testable
• Discover a flaw at the component level? Write unit tests first to expose it (reproduce it). Then fix the error.
• Run tests prior to committing (or merging) your code
![Page 15: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/15.jpg)
Start Simple• Test methods with no dependencies
• Make sure constructor doesn’t have dependencies
input Method output
![Page 16: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/16.jpg)
NUnit Demo (2017)• Add a new project to your solution: Visual C# -> Test
• Remove MSTest parts: reference, using and packages.config
Microsoft.VisualStudio.QualityTools.UnitTestFramework //using Microsoft.VisualStudio.TestTools.UnitTesting <package id=“MSTest.TestAdapter” version=“1.1.11” targetFramework=“net452” /> …
• Add NUnit to your test project using NuGet, packages:
NUnit v3.2.0
NUnit3TestAdapter v.3.0.9-ctp-9 (needs “Include prerelease” checked)
• Add MVC framework using NuGet (since separate project isn’t an MVC app)
Microsoft.AspNet.Mvc (Match the version # of your main project, mine was v.5.2.3)
• Add reference to your own project
Had to delete %AppData$/NuGet/NuGet.Config to load “online” package sources
![Page 17: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/17.jpg)
• Add Visual Studio Test Generator
• Optionally install Visual Studio Test Adapter as an extension rather than locally within the project
• Restart Visual Studio and finish installation
![Page 18: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/18.jpg)
Find something to test
![Page 19: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/19.jpg)
Write your unit test class:
![Page 20: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/20.jpg)
Run Tests: Test -> Windows -> Test Explorer
![Page 21: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/21.jpg)
Harder
input
Function
output
Database
Internet
![Page 22: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/22.jpg)
Not Unit Testable
![Page 23: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/23.jpg)
Not Unit Testable
![Page 24: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/24.jpg)
Why Not?
• “Uncontrolled” dependencies
• All or most functionality in 1 method, with no separation and no “control” over it
• Code is doing more than 1 thing
![Page 25: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/25.jpg)
Arrange — Act — Assert• Arrange
Set up for the test. Configure the system one way or another. Must be able to do this.
• Act
Execute or invoke something, with some input, to obtain some output. Must be able to do this.
• Assert
Usually the easy part.
![Page 26: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/26.jpg)
SOLID• Single responsibility principle
a class (module, method or function) should do one thing and one thing only
• Open/closed principle
• Liskov substitution principle it should be possible to substitute in fakes, stubs or mocks without fundamentally changing anything
• Interface segregation principle create segregation of responsibilities and become agnostic of implementors by replacing concrete classes with interfaces (having the minimum of functionality required)
• Dependency inversion principle (and Inversion of Control) invert the “high-level module depends on low-level module” pattern. Break direct dependencies by using dependency injection pattern and providers.
https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
![Page 27: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/27.jpg)
The Art of Unit Testing, by R Osherov
![Page 28: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/28.jpg)
![Page 29: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/29.jpg)
![Page 30: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/30.jpg)
![Page 31: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/31.jpg)
![Page 32: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/32.jpg)
![Page 33: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/33.jpg)
Problem?
Just a stub for now
![Page 34: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/34.jpg)
One Solution: inject via
constructor
will be other logic here, i.e. test the name not just the extension
![Page 35: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/35.jpg)
![Page 36: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/36.jpg)
![Page 37: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/37.jpg)
• Up Next …
• Testing code that reads/writes to a database
• Use a “mocking framework” to make it easier, i.e.
• Moq: https://github.com/Moq/moq4
• Use [SetUp] and [TearDown] to seed your mock object
![Page 38: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/38.jpg)
Controller
DbContext
EntityFramework
Database
Default Setup
![Page 39: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/39.jpg)
Controller
DbContext
EntityFramework
Database
Using Repository Pattern
ActualRepoForTestingRepo
ISomethingRepository
An interface
![Page 40: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/40.jpg)
Need to modify to allow constructor
injection
![Page 41: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/41.jpg)
Inject mock object
![Page 42: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/42.jpg)
Sports Store Example from
Entity - Single table
![Page 43: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/43.jpg)
Break dependency with Repository pattern
![Page 44: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/44.jpg)
pagination
constructor injection
![Page 45: Unit Testing inmorses/classes/cs46x/lecture/... · 2018-09-24 · •Test individual components (units) • in isolation • to confirm preexisting specification. • Inputs …](https://reader033.vdocuments.net/reader033/viewer/2022050519/5fa317b2d6e41c67313083ef/html5/thumbnails/45.jpg)
Unit Test Pagination