I don't know of any situation where it would be a good idea to have multiple assertions inside the [Test] method itself. The main reason people like to have multiple Assertions is they are trying to have a one [TestFixture] class for each class being tested. Instead, you can break up your tests into more [TestFixture] classes. This allows you to see multiple ways in which the code may not have reacted in the way you expected, instead of just the one where the first assertion failed. The way you achieve this is you have at least one directory per class being tested with lots of [TestFixture] classes inside. Each [TestFixture] class would be named after the specific state of an object you will be testing. The [SetUp] method will get the object into the state described by the class name. Then you have multiple [Test] methods each asserting different things you would expect to be true, given the object's current state. Each [Test] method is named after the thing it is asserting, except perhaps it might be named after the concept instead of just an English readout of the code. Then each [Test] method implementation only needs a single line of code where it is asserting something.
Usually this means that the final line of code inside the [SetUp] method should store a property value or return value in a private instance variable of the [TestFixture]. Then you might assert multiple different things about this instance variable from different [Test] methods. You also might make assertions about what different properties of the object under test are set to now that it is in the desired state.
Sometimes you need to make assertions along the way as you are getting the object under test into the desired state in order to make sure you did not mess up before getting the object into the desired state. In that case, those extra assertions should appear inside the [SetUp] method. If something goes wrong inside the [SetUp] method, it will be clear that something was wrong with the test before the object ever got into the desired state you intended to test.
One other problem you may run into is you may be testing an Exception that you expected to be thrown. This can tempt you into not following the above model. However, it can still be achieved by catching the exception inside the [SetUp] method and storing it into an instance variable. This will allow you to assert different things about the exception, each in it's own [Test] method. You can then also assert other things about the object under test to make sure there were no unintended side effects from the exception being thrown.
Example (this would be broken up into multiple files):
namespace Tests.AcctTests { [TestFixture] public class no_events { private Acct _acct; [SetUp] public void SetUp() { _acct = new Acct(); } [Test] public void balance_0() { Assert.That(_acct.Balance, Is.EqualTo(0m)); } } [TestFixture] public class try_withdraw_0 { private Acct _acct; private List<string> _problems; [SetUp] public void SetUp() { _acct = new Acct(); Assert.That(_acct.Balance, Is.EqualTo(0)); _problems = _acct.Withdraw(0m); } [Test] public void has_problem() { Assert.That(_problems, Is.EquivalentTo(new string[] { "Withdraw amount must be greater than zero." })); } [Test] public void balance_not_changed() { Assert.That(_acct.Balance, Is.EqualTo(0m)); } } [TestFixture] public class try_withdraw_negative { private Acct _acct; private List<string> _problems; [SetUp] public void SetUp() { _acct = new Acct(); Assert.That(_acct.Balance, Is.EqualTo(0)); _problems = _acct.Withdraw(-0.01m); } [Test] public void has_problem() { Assert.That(_problems, Is.EquivalentTo(new string[] { "Withdraw amount must be greater than zero." })); } [Test] public void balance_not_changed() { Assert.That(_acct.Balance, Is.EqualTo(0m)); } } }