开发者

mocking a method while calling a method in same service class groovy grails

开发者 https://www.devze.com 2023-02-14 09:53 出处:网络
im开发者_Go百科 looking for something similar to what i would do with rhino mocks but in groovy.

im开发者_Go百科 looking for something similar to what i would do with rhino mocks but in groovy.

i sometimes use partial mocks as well.

in ASP -- Rhino mocks

const string criteria = "somecriteriahere";
ISomeRepository mockSomeRepository = MockRepository.GenerateStrictMock<SomeRepository>();
mockSomeRepository.Expect(m => m.GetSomesByNumber(criteria)).Return(new List<Some>() { });
mockSomeRepository.Expect(m => m.GetSomesByName(criteria)).Return(new List<Some>() { });
mockSomeRepository.Expect(m => m.GetSomesByOtherName(criteria)).Return(new List<Some>() { });

mockSomeRepository.SearchForSomes(criteria);
mockSomeRepository.VerifyAllExpectations();

--------note the virtual -------

public class SomeRepository : ISomeRepository {
    public virtual IEnumerable<Some> GetSomesByNumber(string num)
        {
        //some code here
        }

        public virtual IEnumerable<Some> GetSomesByName(string name)
        {
        //some code here
        }

        public virtual IEnumerable<Some> GetSomesByOtherName(string name)
        {
        //some code here
        }

        public IEnumerable<Some> SearchForSomes(string criteria) {
        this.GetSomesByNumber(criteria); //tested fully seperatly
        this.GetSomesByName(criteria); //tested fully seperatly
        this.GetSomesByOtherName(criteria); //tested fully seperatly

        //other code to be tested
    }
}

GetSomesByNumber, GetSomesByName, GetSomesByOtherName would be tested fully seperatly. If i actually provided values and went into those functions, to me, that seems like in integration test where im testing multiple functionalities and not one unit of work.

So, SearchForSomes i would only be testing that method and mocking away all other dependencies.

In Grails

class XService {

    def A() {
    }

    def B() {
        def result = this.A()
        //do some other magic with result
    }
}

I have tried this -- but failed

        def XServiceControl = mockFor(XService)
        XServiceControl.demand.A(1..1) { -> return "aaa" }

        //  Initialise the service and test the target method.

        //def service = XServiceControl.createMock();

        //def service = XServiceControl.proxyInstance()

        // Act
        //def result = XServiceControl.B(_params);
        XServiceControl.use {
                new XService().B(_params)
       }

Ive got no idea how to do this, does any one know how?

Thanks


If you're using groovy MockFor (e.g. groovy.mock.interceptor.MockFor), then you need to enclode the usage in a .use{} block.

However, it looks like you are calling mockFor from within a grails.test.GrailsUnitTestCase. In that case, there's no need for the .use{} block: the scope of the mock is the whole test.


thanks for your reply ataylor

seem what i was trying to accomplish is something called partial/half mocking. Here are some links.

http://www.gitshah.com/2010/05/how-to-partially-mock-class-and-its.html

http://mbrainspace.blogspot.com/2010/02/partial-half-mocks-why-theyre-good-real.html

https://issues.apache.org/jira/browse/GROOVY-2630

https://issues.apache.org/jira/browse/GROOVY-1823

http://java.dzone.com/articles/new-groovy-171-constructor

I didnt accomplish this, i ended up extracting B() into its own class and injecting a mock of XService into B's class -- Dependency Injection. I was also informed that extracting away dependencies is a better practice for testing. So, i am now very carefull when using this.() :D

0

精彩评论

暂无评论...
验证码 换一张
取 消