So as usual with so many of .NET 1.0 to .NET 2.0 era classes, Microsoft have made it near impossible to mock out MembershipProvider. The MembershipProvidersCollection class is read-only so you can’t just add your own provider at runtime.
No matter! After some time with Reflector and some twiddling with reflection I came up with a way to add a mocked out MembershipProvider.
public static void AddMembershipProvider(this ProviderCollection providers, string providerName, MembershipProvider provider) { GetMembershipHashtable().Add(providerName, provider); } public static void RemoveMembershipProvider(this ProviderCollection providers, string providerName) { GetMembershipHashtable().Remove(providerName); } static Hashtable GetMembershipHashtable() { var hashtableField = typeof(ProviderCollection).GetField("_Hashtable", BindingFlags.Instance | BindingFlags.NonPublic); return hashtableField.GetValue(Membership.Providers) as Hashtable; }
I then called the above methods from my SetUp and TearDown methods so as to ensure the next test doesn’t run with the same providers. I’m using Moq to generate the mocks in the example code below:
private Mock<MembershipProvider> _membership; private MockFactory _factory; [SetUp] public override void Setup() { _factory = new MockFactory(MockBehavior.Strict); _membership = _factory.Create<MembershipProvider>(); Membership.Providers.AddMembershipProvider("MyMembershipProvider", _membership.Object); } [TearDown] public override void Teardown() { Membership.Providers.RemoveMembershipProvider("MyMembershipProvider"); }
I know you’re not supposed to access private variables blah blah because they can change blah blah break your code blah blah blah but I don’t care. The code is all in one place and my unit tests are part of my continuous build. If Microsoft happen to decide to change the implementation, I should get a notification from TeamCity as soon as I upgrade. In the meantime, I’ll be happily unit testing my code.
Okay, this took me far too long to figure this out. Mainly due to my own misunderstanding of Python terminology regarding modules (For the record, a ‘module’ is a file not a directory of python files) and mainly because I couldn’t find a specific example for what I wanted to achieve. My goal was this: Given a directory full of unit tests, run all the unit tests that can be found. I wanted to be able to drop in new unit tests without having to include them somewhere.
This is what I managed to come up with:
#!/usr/bin/python import unittest2 as unittest if __name__ == "__main__": all_tests = unittest.TestLoader().discover('tests', pattern='*.py') unittest.TextTestRunner().run(all_tests)
It uses the (apparently) new discover method. I’m still using Python 2.6 which doesn’t have access to this method so I had to install unittest2 which is a backport from Python 2.7. If you do happen to be running Python 2.7, you can simply run this (found in the unittest documentation):
python -m unittest discover project_directory ‘*.py’
4 hours later and it’s 2 lines of code (WHICH I KNEW IT WOULD BE! AAARGH!). No matter. I won’t forget my module lesson in a hurry.
21 Apr
Posted by Richard as Uncategorized
I was sitting with the problem that every time I connected to my company’s VPN my internet stopped working. After trawling through through a bug on Launchpad, I came across a solution. Basically, do the following:
What’s going on here is the concept of split tunneling. This is where you can access the Internet and your company network at the same time. What I wasn’t aware of is that this is actually a vulnerability. I have my own firewall at home so I feel that this protects the internal network from the big bad Internet.
What’s confusing is that on Windows, this is the default behavior of the cisco client (not surprising as it is less secure, but more usable). It seems like a sensible default for Linux but it’s a little frustrating trying to find the solution. From a usability perspective, I would suggest that the option be more prominent for the user. When you select it, a dialog could be displayed that briefly describes the risk to the user.
I recently pulled my hair out looking for how to enable echo during a windows telnet session. Turns out it’s pretty straightforward (as it usually is…)
And that’s it.
26 Jan
Posted by Rachel as Code, Java, Spring MVC
In the second part of this tutorial, we got to the point of being able to load entities from the database and display them on a page.
For this tutorial, we will handle the creation of a new Entry object with a form, handle the submission of the form and redirect after post back to the list of entries that we created in part 2 of this tutorial.
The user must be able to navigate to a form where they can enter a title and some text for a new blog entry. The user must be able to save this entry by submitting a form and should then be redirected to a list of all existing blog entries. If the user hits refresh on the list of blog entries, the most recent entry should not be duplicated.
Firstly, we’re going to need to map a url for this new action. To accomplish this we need to change the ParameterizedUrlHandlerMapping section of the spring-servlet.xml file.
<bean class="carbonfive.spring.web.pathparameter.ParameterizedUrlHandlerMapping"> <property name="alwaysUseFullPath" value="false" /> <property name="interceptors"> <list> <ref bean="hibernateInterceptorSessionInView" /> </list> </property> <property name="defaultHandler" ref="homeController"/> <property name="mappings"> <props> <prop key="/index">homeController</prop> <prop key="/entry/create">createEntryController</prop> </props> </property> </bean> <bean id="createEntryController" class="com.tutorial.webapp.EntryCreateController"> <property name="formView" value="entryform" /> </bean>
To be able to save our entry, we need to add a save method to our EntryRepository.
@Transactional(readOnly = false) public void store(Entry entry) { Session session = sessionFactory.getCurrentSession(); session.save(entry); session.flush(); }
For our form controller, we can extend an existing Spring Controller class called the SimpleFormController. This class makes it simple to specify a form view, a success view and your command object.
Lets discuss what you will see in the controller class.
@Controller public class EntryControllerCreate extends SimpleFormController { @Autowired private EntryRepository entryRepository; @RequestMapping(method = RequestMethod.GET) public String showForm( HttpServletRequest request, HttpServletResponse response, ModelMap model) { model.put("entry", new Entry()); return getFormView(); } @RequestMapping(method = RequestMethod.POST) public String processSubmit( @ModelAttribute("entry")Entry entry, HttpServletRequest request, HttpServletResponse response, SessionStatus status, ModelMap model){ entryRepository.store(entry); return "redirect:"+getSuccessView(); } }
Then we need an html file to put the form on.
[#import "/spring.ftl" as spring /]
<html>
<head>
<title>Create Entry</title>
</head>
<body>
<form method="post" id="entry" name="entryForm">
<p>
<button class="button" type="submit" name="submit" id="update">Update</button>
<br/>Entry Title: [@spring.formInput "entry.title"/]
<br/>Entry Text: [@spring.formInput "entry.text"/]
</p>
<br/>
</form>
</body>
</html>You should now be able to run the application and create a blog entry with a title and some text.
In this example we aren’t going to handle any errors – we’ll cover that in another tutorial at a later stage.
While this is best practise it is not a hard and fast rule. The main reason behind it is that if you don’t redirect, the user can refresh the page and the form will be resubmitted. In some cases this can be the desired behaviour (checking availability of tickets) and in some cases it is really undesired (resubmitting payment information).
In each case it’s up to you to decide what will be best for your users.
We will update our code to be able to handle editing entries.