I am less concerned about DRY code in unit tests, and more concerned about the test clearly stating the intended behavior. Doc Brown has sensible advice, but I would prefer the assert in each test.
If having no unsaved changes is one of the expected behaviors of the system under test, put the assert in the test. Yes, it is a repeated line of code, but refactoring it into a private method can clean that up. The important thing is the test clearly indicates that having no unsaved changes is the desired behavior, and this fact is traceable from the test itself. It makes the test easier to understand later when you come back and read it, because you don't need to remember that the cleanup code is magically called by the test framework. You can see from the test exactly how the control flow leads to the failure.
I've written tests that performed asserts in a cleanup method. While I could trace through code to identify which test case was failing, it was always a jarring experience. The failure wasn't immediately obvious, because the stack trace referenced methods from the test framework itself in between the failure and the test method.
Placing asserts in the test cleanup might appear safe, and might not appear to interfere with disposing of resources, but I'm always leary about purposefully throwing exceptions in cleanup code. A change in some other location of the application or test could prevent resources from being disposed of properly. This can cause a cascade of failures that are unrelated to the original failure, which complicates the trouble-shooting process. For this reason alone I like to keep asserts and cleanup code separate, so that one does not affect the other.
Think of it as adhering to the Single Responsibility Principal in your test code. The system under test and the cleanup are separate concerns, and change for different reasons. They have different responsibilities, and therefore deserve different treatments in your test code.