Background
Usually, Moq is used during Unit Testing (i.e. one single class or system layer under test), whereas Selenium would imply browser automation testing and your Selenium Unit Test would be out of process of your WebForm. One primary benefit of a mock is that it offers the ability to verify / spy on the system under test, which typically requires in-process instantiation of the class you want to test, and direct injection of the mocked dependencies - AFAIK this will be lost when run out of process (when testing with Se, you are looking to test the application in its deployed state).
IMO WebForms pages aren't really conducive to this kind of unit testing with Moq since:
- It is difficult to create a
WebForm
directly and in isolation, given the large number of environmental dependencies - e.g. the page lifecycle would need to be simulated, and HttpContext
, Session
provided, etc.
System.Web.Page
wasn't designed for Constructor or Setter injection
However, that said, there is still hope:
- It is possible to apply a retrofit to get a Dependency Inversion principle mechanism working with WebForms.
- Although you will lose the verification features of
Moq
when run out of process, you can still use Moq to Stub your dependency and to return fake data to the WebForm (e.g. a Stub of your IRepository
dependency). In order to perform verifications, you will however need to find another mechanism to record invocations on your dependency, e.g. by recording to the filesystem or a database (or somehow marshall the Moq back to the Se Unit Test).
So here's an idea:
- Ensure the WebForms access to your repository dependency is decoupled via an interface, and then use a Service Locator(1) to obtain instances of your repository dependency for use by your WebForm (most IoC containers support both DI and Service Locator, e.g. Unity).
- Move the BootStrap configuration (e.g. Unity RegisterInstance / RegisterType) into configuration (2). This way you can substitute your actual repository out, without having to edit IoC bootstrap code e.g. in
Global.asax
to switch between real and fake repositories.
- Create a Stub / Mock repository in a separate assembly (if you used Moq, you would probably need to provide a factory to the IoC which creates the Moq, and returns the
mock.Object
), which records each invocation, and the parameters, and a timestamp, to a database.
- Copy this assembly to your Dev web server, and edit the IoC config to redirect the
IRepository
interface to point to your fake repository.
- Do your Selenium tests. After each action, you then need to query the verification database to assert the correct number of calls. You'll also need to do clean up before / after each test.
(1) In most scenarios, Dependency Injection should be preferred to Service Locator , however
(2) Again, this isn't best practice, as compile time safety can be lost. IoC's usually do however have a "Validate" configuration mechanism which can at least partially compensate for this.
Or
You could consider instead to move your presentation tier off WebForms, onto ASP.Net MVC, where Dependency Injection and Unit Testing are first class citizens, and Moq verification is accessible ;)