我使用很多Web应用程序,这些应用程序由后端不同复杂程度的数据库驱动.通常,存在与业务和表示逻辑分离的ORM层.这使得对业务逻辑的单元测试相当简单; 事物可以在离散模块中实现,测试所需的任何数据都可以通过对象模拟来伪造.
但是测试ORM和数据库本身一直充满了问题和妥协.
多年来,我尝试了一些策略,其中没有一个完全满足我.
使用已知数据加载测试数据库.针对ORM运行测试并确认正确的数据返回.这里的缺点是您的测试数据库必须跟上应用程序数据库中的任何模式更改,并且可能会不同步.它还依赖于人工数据,并且可能不会暴露由于愚蠢的用户输入而发生的错误.最后,如果测试数据库很小,它将不会显示缺失索引等低效率.(好吧,最后一个不是真的应该使用单元测试,但它没有受到伤害.)
加载生产数据库的副本并对其进行测试.这里的问题是你可能不知道在任何给定时间生产数据库中有什么; 如果数据随时间变化,您的测试可能需要重写.
有些人指出,这两种策略都依赖于特定的数据,单元测试应该只测试功能.为此,我见过建议:
您使用了哪些策略来测试数据库驱动的应用程序?什么对你有用?
我写了一个工厂来生产java.sql.Connection物品:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
    @Override public Connection getConnection() {
        try {
            return DriverManager.getConnection(...);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
我想验证传递给的参数DriverManager.getConnection,但我不知道如何模拟静态方法.我正在使用JUnit 4和Mockito来测试我的测试用例.有没有一种很好的方法来模拟/验证这个特定的用例?
我正在尝试使用Mockito测试一些遗留代码.
我想FooDao在生产中使用如下的存根:
foo = fooDao.getBar(new Bazoo());
Run Code Online (Sandbox Code Playgroud)
我可以写:
when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);
Run Code Online (Sandbox Code Playgroud)
但显而易见的问题是,getBar()永远不会使用Bazoo我为该方法存根的相同对象调用.(诅咒那个new操作员!)
如果我能以一种myFoo不管参数而返回的方式存根方法,我都会喜欢它.如果做不到这一点,我会听取其他的解决方法建议,但我真的希望避免更改生产代码,直到有合理的测试覆盖率.
有没有办法让stubbed方法在后续调用中返回不同的对象?我想这样做来测试一个非确定的响应ExecutorCompletionService.即,无论方法的返回顺序如何进行测试,结果都保持不变.
我想要测试的代码看起来像这样.
// Create an completion service so we can group these tasks together
ExecutorCompletionService<T> completionService =
        new ExecutorCompletionService<T>(service);
// Add all these tasks to the completion service
for (Callable<T> t : ts)
    completionService.submit(request);
// As an when each call finished, add it to the response set.
for (int i = 0; i < calls.size(); i ++) {
    try {
        T t = completionService.take().get();
        // do some stuff that I want to test
    } catch (...) { } …Run Code Online (Sandbox Code Playgroud) 我有一个方法调用,我想用mockito模拟.首先,我创建并注入了一个将在其上调用方法的对象实例.我的目的是验证方法调用中的一个对象.
有没有一种方法可以让mockito在调用mock方法时断言或验证对象及其属性?
例
Mockito.verify(mockedObject)
       .someMethodOnMockedObject(
              Mockito.<SomeObjectAsArgument>anyObject())
Run Code Online (Sandbox Code Playgroud)
而不是anyObject()我想检查该参数对象包含一些特定的字段
Mockito.verify(mockedObject)
       .someMethodOnMockedObject(
              Mockito.<SomeObjectAsArgument>**compareWithThisObject()**)
Run Code Online (Sandbox Code Playgroud) 我开始认为这是不可能的,但无论如何我想问.
我想测试我的一个ES6模块以特定方式调用另一个ES6模块.使用Jasmine这非常容易 -
应用代码:
// myModule.js
import dependency from './dependency';
export default (x) => {
  dependency.doSomething(x * 2);
}
Run Code Online (Sandbox Code Playgroud)
和测试代码:
//myModule-test.js
import myModule from '../myModule';
import dependency from '../dependency';
describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    spyOn(dependency, 'doSomething');
    myModule(2);
    expect(dependency.doSomething).toHaveBeenCalledWith(4);
  });
});
Run Code Online (Sandbox Code Playgroud)
什么与Jest相当?我觉得这是一件非常简单的事情,但我一直在试图弄清楚我的头发.
我最接近的import是用requires 替换s,并在测试/函数内移动它们.这些都不是我想要做的事情.
// myModule.js
export default (x) => {
  const dependency = require('./dependency'); // yuck
  dependency.doSomething(x * 2);
}
//myModule-test.js
describe('myModule', () => {
  it('calls the …Run Code Online (Sandbox Code Playgroud) 我有简单的集成测试
    @Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception {
    mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
            .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
            .andDo(print())
            .andExpect(status().isBadRequest())
            .andExpect(?);
}
Run Code Online (Sandbox Code Playgroud)
在最后一行中,我想将响应体中收到的字符串与期望的字符串进行比较
作为回应,我得到:
MockHttpServletResponse:
          Status = 400
   Error message = null
         Headers = {Content-Type=[application/json]}
    Content type = application/json
            Body = "Username already taken"
   Forwarded URL = null
  Redirected URL = null
Run Code Online (Sandbox Code Playgroud)
尝试使用content(),body()但没有任何效果.
所以,我正在创建一个模拟对象作为类级别的静态变量,如此...在一个测试中,我想Foo.someMethod()返回一个特定的值,而在另一个测试中,我希望它返回一个不同的值.我遇到的问题是,似乎我需要重建模拟才能使其正常工作.我想避免重建模拟,并在每次测试中使用相同的对象.
class TestClass {
    private static Foo mockFoo;
    @BeforeClass
    public static void setUp() {
        mockFoo = mock(Foo.class);
    }
    @Test
    public void test1() {
        when(mockFoo.someMethod()).thenReturn(0);
        TestObject testObj = new TestObject(mockFoo);
        testObj.bar(); // calls mockFoo.someMethod(), receiving 0 as the value
    }
    @Test
    public void test2() {
        when(mockFoo.someMethod()).thenReturn(1);
        TestObject testObj = new TestObject(mockFoo);
        testObj.bar(); // calls mockFoo.someMethod(), STILL receiving 0 as the value, instead of expected 1.
    }
}
Run Code Online (Sandbox Code Playgroud)
在第二个测试中,当调用testObj.bar()时,我仍然接收0作为值...解决此问题的最佳方法是什么?请注意,我知道我可以Foo在每个测试中使用不同的模拟,但是,我必须将多个请求链接起来mockFoo,这意味着我必须在每个测试中进行链接.
我正在尝试使用Pythons mock包来模拟Pythons requests模块.让我在以下场景中工作的基本要求是什么?
在我的views.py中,我有一个函数可以使每次request.get()调用具有不同的响应
def myview(request):
  res1 = requests.get('aurl')
  res2 = request.get('burl')
  res3 = request.get('curl')
Run Code Online (Sandbox Code Playgroud)
在我的测试类中,我想做类似的事情,但无法弄清楚确切的方法调用
步骤1:
# Mock the requests module
# when mockedRequests.get('aurl') is called then return 'a response'
# when mockedRequests.get('burl') is called then return 'b response'
# when mockedRequests.get('curl') is called then return 'c response'
Run Code Online (Sandbox Code Playgroud)
第2步:
打电话给我
第3步:
验证响应包含'响应','b响应','c响应'
如何完成步骤1(模拟请求模块)?
mocking ×10
java ×7
mockito ×6
unit-testing ×5
database ×1
ecmascript-6 ×1
javascript ×1
jestjs ×1
junit ×1
node.js ×1
orm ×1
python ×1
request ×1
spring ×1