nsubstitute / NSubstitute

A friendly substitute for .NET mocking libraries.
https://nsubstitute.github.io
Other
2.67k stars 263 forks source link

Non virtual methods on a class automatically pass in testing framework .Received().XXX is called. #166

Closed 4imble closed 7 years ago

4imble commented 10 years ago

Both the assertions below pass when .Execute is not virtual. This was confusing me for a while. I ended up swapping out NS for Moq and Moq reported an error informing me of the problem. It would be nice if NS did this too to save confusion.

//Using MSpec

public class When_told_to_execute_all_it_should_execute_all_commands : WithSubject { static AddTaskCommand command1; static AddTaskCommand command2;

   Establish context = () =>
       {
           command1 = An<AddTaskCommand>();
           command2 = An<AddTaskCommand>();
           Subject.AcceptCommand(command1);
           Subject.AcceptCommand(command2);
       };

   Because of = () => Subject.ExecuteAll();

   It should_have_called_execute_on_command_1 = () => command1.WasToldTo(x => x.Execute());
   It should_have_called_execute_on_command_2 = () => command2.Received().Execute();
  }

http://stackoverflow.com/questions/26711633/how-to-assert-method-called-in-mspec-with-nsubstitute/26712964#26712964

Just tried FakeItEasy too, which is also reporting a nice error message when the method is not virtual.

dtchepak commented 10 years ago

This is a limitation with NSubstitute's syntax. When Received() is called it doesn't actually know what call is going to come next. If it never intercepts a call (i.e. a non-virtual is called) then it won't know something is wrong. (There is a bit more on how NSub works on this post by Jake, starting at the section "NSubstitute Tradeoffs".)

I'll leave this issue open as I can have a look at improving the detection of these cases. Unfortunately it can result in things like other tests failing, but it might be better than nothing.

dtchepak commented 7 years ago

Closing until we get a proposal for working around this. I think it is a limitation of NSub's syntax.